5.15.198-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 271/554 usb: usb-storage: No additional quirks need to be added to the EL-R12 optical drive.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Changcheng <[email protected]>
[ Upstream commit 955a48a5353f4fe009704a9a4272a3adf627cd35 ]
The optical drive of EL-R12 has the same vid and pid as INIC-3069, as follows:
T: Bus=02 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 3 Spd=5000 MxCh= 0 D: Ver= 3.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=13fd ProdID=3940 Rev= 3.10 S: Manufacturer=HL-DT-ST S: Product= DVD+-RW GT80N S: SerialNumber=423349524E4E38303338323439202020 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=144mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=02 Prot=50 Driver=usb-storage E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=0a(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
This will result in the optical drive device also adding the quirks of US_FL_NO_ATA_1X. When performing an erase operation, it will fail, and the reason for the failure is as follows:
[ 388.967742] sr 5:0:0:0: [sr0] tag#0 Send: scmd 0x00000000d20c33a7 [ 388.967742] sr 5:0:0:0: [sr0] tag#0 CDB: ATA command pass through(12)/Blank a1 11 00 00 00 00 00 00 00 00 00 00 [ 388.967773] sr 5:0:0:0: [sr0] tag#0 Done: SUCCESS Result: hostbyte=DID_TARGET_FAILURE driverbyte=DRIVER_OK cmd_age=0s [ 388.967773] sr 5:0:0:0: [sr0] tag#0 CDB: ATA command pass through(12)/Blank a1 11 00 00 00 00 00 00 00 00 00 00 [ 388.967803] sr 5:0:0:0: [sr0] tag#0 Sense Key : Illegal Request [current] [ 388.967803] sr 5:0:0:0: [sr0] tag#0 Add. Sense: Invalid field in cdb [ 388.967803] sr 5:0:0:0: [sr0] tag#0 scsi host busy 1 failed 0 [ 388.967803] sr 5:0:0:0: Notifying upper driver of completion (result 8100002) [ 388.967834] sr 5:0:0:0: [sr0] tag#0 0 sectors total, 0 bytes done.
For the EL-R12 standard optical drive, all operational commands and usage scenarios were tested without adding the IGNORE_RESIDUE quirks, and no issues were encountered. It can be reasonably concluded that removing the IGNORE_RESIDUE quirks has no impact.
--- drivers/usb/storage/unusual_uas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/unusual_uas.h +1 -1
@@ -98,7 +98,7 @@ UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160, US_FL_NO_ATA_1X),/* Reported-by: Benjamin Tissoires <[email protected]> */ -UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, +UNUSUAL_DEV(0x13fd, 0x3940, 0x0309, 0x0309, "Initio Corporation", "INIC-3069", USB_SC_DEVICE, USB_PR_DEVICE, NULL,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 272/554 serial: sprd: Return -EPROBE_DEFER when uart clock is not ready
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenhua Lin <[email protected]>
[ Upstream commit 29e8a0c587e328ed458380a45d6028adf64d7487 ]
In sprd_clk_init(), when devm_clk_get() returns -EPROBE_DEFER for either uart or source clock, we should propagate the error instead of just warning and continuing with NULL clocks.
Currently the driver only emits a warning when clock acquisition fails and proceeds with NULL clock pointers. This can lead to issues later when the clocks are actually needed. More importantly, when the clock provider is not ready yet and returns -EPROBE_DEFER, we should return this error to allow deferred probing.
This change adds explicit checks for -EPROBE_DEFER after both:
1. devm_clk_get(uport->dev, uart)
2. devm_clk_get(uport->dev, source)
When -EPROBE_DEFER is encountered, the function now returns -EPROBE_DEFER to let the driver framework retry probing later when the clock dependencies are resolved.
--- drivers/tty/serial/sprd_serial.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/tty/serial/sprd_serial.c +6 -0
@@ -1137,6 +1137,9 @@ static int sprd_clk_init(struct uart_port *uport) clk_uart =devm_clk_get (uport->dev,"uart" );if (IS_ERR (clk_uart)) { +if (PTR_ERR (clk_uart) == -EPROBE_DEFER ) +return -EPROBE_DEFER ; +dev_warn (uport->dev,"uart%d can't get uart clock\n" , uport->line); clk_uart =NULL ;
@@ -1144,6 +1147,9 @@ static int sprd_clk_init(struct uart_port *uport) clk_parent =devm_clk_get (uport->dev,"source" );if (IS_ERR (clk_parent)) { +if (PTR_ERR (clk_parent) == -EPROBE_DEFER ) +return -EPROBE_DEFER ; +dev_warn (uport->dev,"uart%d can't get source clock\n" , uport->line); clk_parent =NULL ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 273/554 nvme-fc: dont hold rport lock when putting ctrl
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Wagner <[email protected]>
[ Upstream commit b71cbcf7d170e51148d5467820ae8a72febcb651 ]
nvme_fc_ctrl_put can acquire the rport lock when freeing the ctrl object:
nvme_fc_ctrl_put
nvme_fc_ctrl_free
spin_lock_irqsave(rport->lock)
Thus we can't hold the rport lock when calling nvme_fc_ctrl_put.
Justin suggested use the safe list iterator variant because nvme_fc_ctrl_put will also modify the rport->list.
--- drivers/nvme/host/fc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/nvme/host/fc.c +4 -2
@@ -1500,14 +1500,14 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport, {struct fcnvme_ls_disconnect_assoc_rqst *rqst = &lsop->rqstbuf->rq_dis_assoc; -struct nvme_fc_ctrl *ctrl, *ret =NULL ; +struct nvme_fc_ctrl *ctrl, *tmp, *ret =NULL ;struct nvmefc_ls_rcv_op *oldls =NULL ;u64 association_id =be64_to_cpu (rqst->associd.association_id);unsigned long flags;spin_lock_irqsave (&rport->lock, flags); -list_for_each_entry (ctrl, &rport->ctrl_list, ctrl_list) { +list_for_each_entry_safe (ctrl, tmp, &rport->ctrl_list, ctrl_list) {if (!nvme_fc_ctrl_get (ctrl))continue ;spin_lock (&ctrl->lock);
@@ -1520,7 +1520,9 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport,if (ret)/* leave the ctrl get reference */ break ; +spin_unlock_irqrestore (&rport->lock, flags);nvme_fc_ctrl_put (ctrl); +spin_lock_irqsave (&rport->lock, flags); }spin_unlock_irqrestore (&rport->lock, flags);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 274/554 platform/x86/intel/hid: Add Dell Pro Rugged 10/12 tablet to VGBS DMI quirks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chia-Lin Kao (AceLan) <[email protected]>
[ Upstream commit b169e1733cadb614e87f69d7a5ae1b186c50d313 ]
Dell Pro Rugged 10/12 tablets has a reliable VGBS method.
If VGBS is not called on boot, the on-screen keyboard won't appear if the device is booted without a keyboard.
Call VGBS on boot on thess devices to get the initial state of SW_TABLET_MODE in a reliable way.
--- drivers/platform/x86/intel/hid.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/platform/x86/intel/hid.c +12 -0
@@ -144,6 +144,18 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 10 Tablet RA00260"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, { } };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 275/554 vhost/vsock: improve RCU read sections around vhost_vsock_get()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Garzarella <[email protected]>
[ Upstream commit d8ee3cfdc89b75dc059dc21c27bef2c1440f67eb ]
vhost_vsock_get() uses hash_for_each_possible_rcu() to find the vhost_vsock associated with the guest_cid. hash_for_each_possible_rcu() should only be called within an RCU read section, as mentioned in the following comment in include/linux/rculist.h:
/**
* hlist_for_each_entry_rcu - iterate over rcu list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
* @cond: optional lockdep expression if called from non-RCU protection.
*
* This list-traversal primitive may safely run concurrently with
* the _rcu list-mutation primitives such as hlist_add_head_rcu()
* as long as the traversal is guarded by rcu_read_lock(). */
Currently, all calls to vhost_vsock_get() are between rcu_read_lock() and rcu_read_unlock() except for calls in vhost_vsock_set_cid() and vhost_vsock_reset_orphans(). In both cases, the current code is safe, but we can make improvements to make it more robust.
About vhost_vsock_set_cid(), when building the kernel with CONFIG_PROVE_RCU_LIST enabled, we get the following RCU warning when the user space issues ioctl(dev, VHOST_VSOCK_SET_GUEST_CID, ...) :
WARNING: suspicious RCU usage
6.18.0-rc7 #62 Not tainted
-----------------------------
drivers/vhost/vsock.c:74 RCU-list traversed in non-reader section!!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
1 lock held by rpc-libvirtd/3443:
#0: ffffffffc05032a8 (vhost_vsock_mutex){+.+.}-{4:4}, at: vhost_vsock_dev_ioctl+0x2ff/0x530 [vhost_vsock]
stack backtrace: CPU: 2 UID: 0 PID: 3443 Comm: rpc-libvirtd Not tainted 6.18.0-rc7 #62 PREEMPT(none) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-7.fc42 06/10/2025 Call Trace: <TASK> dump_stack_lvl+0x75/0xb0 dump_stack+0x14/0x1a lockdep_rcu_suspicious.cold+0x4e/0x97 vhost_vsock_get+0x8f/0xa0 [vhost_vsock] vhost_vsock_dev_ioctl+0x307/0x530 [vhost_vsock] __x64_sys_ioctl+0x4f2/0xa00 x64_sys_call+0xed0/0x1da0 do_syscall_64+0x73/0xfa0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ... </TASK>
This is not a real problem, because the vhost_vsock_get() caller, i.e. vhost_vsock_set_cid(), holds the vhost_vsock_mutex used by the hash table writers. Anyway, to prevent that warning, add lockdep_is_held() condition to hash_for_each_possible_rcu() to verify that either the caller is in an RCU read section or vhost_vsock_mutex is held when CONFIG_PROVE_RCU_LIST is enabled; and also clarify the comment for vhost_vsock_get() to better describe the locking requirements and the scope of the returned pointer validity.
About vhost_vsock_reset_orphans(), currently this function is only called via vsock_for_each_connected_socket(), which holds the vsock_table_lock spinlock (which is also an RCU read-side critical section). However, add an explicit RCU read lock there to make the code more robust and explicit about the RCU requirements, and to prevent issues if the calling context changes in the future or if vhost_vsock_reset_orphans() is called from other contexts.
Message-Id: <[email protected]>
Message-ID: <20251126210313.GA499503@fedora>
--- drivers/vhost/vsock.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/vhost/vsock.c +11 -4
@@ -65,14 +65,15 @@ static u32 vhost_transport_get_local_cid(void)return VHOST_VSOCK_DEFAULT_HOST_CID ; } -/* Callers that dereference the return value must hold vhost_vsock_mutex or the -* RCU read lock. +/* Callers must be in an RCU read section or hold the vhost_vsock_mutex. +* The return value can only be dereferenced while within the section. */ static struct vhost_vsock *vhost_vsock_get (u32 guest_cid) {struct vhost_vsock *vsock; -hash_for_each_possible_rcu (vhost_vsock_hash, vsock, hash, guest_cid) { +hash_for_each_possible_rcu (vhost_vsock_hash, vsock, hash, guest_cid, +lockdep_is_held (&vhost_vsock_mutex)) {u32 other_cid = vsock->guest_cid;/* Skip instances that have no CID yet */
@@ -727,9 +728,15 @@ static void vhost_vsock_reset_orphans(struct sock *sk)* executing. */ +rcu_read_lock (); +/* If the peer is still valid, no need to reset connection */ -if (vhost_vsock_get (vsk->remote_addr.svm_cid)) +if (vhost_vsock_get (vsk->remote_addr.svm_cid)) { +rcu_read_unlock ();return ; + } + +rcu_read_unlock ();/* If the close timeout is pending, let it expire. This avoids races * with the timeout callback.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 276/554 KEYS: trusted: Fix a memory leak in tpm2_load_cmd
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <[email protected]>
commit 62cd5d480b9762ce70d720a81fa5b373052ae05f upstream.
'tpm2_load_cmd' allocates a tempoary blob indirectly via 'tpm2_key_decode' but it is not freed in the failure paths. Address this by wrapping the blob into with a cleanup helper.
--- security/keys/trusted-keys/trusted_tpm2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
security/keys/trusted-keys/trusted_tpm2.c +4 -2
@@ -375,6 +375,7 @@ static int tpm2_load_cmd(struct tpm_chipstruct trusted_key_options *options, u32 *blob_handle) { + u8 *blob_ref __free(kfree) = NULL;struct tpm_buf buf;unsigned int private_len;unsigned int public_len;
@@ -388,6 +389,9 @@ static int tpm2_load_cmd(struct tpm_chip/* old form */ blob = payload->blob; payload->old_format =1 ; + }else { +/* Bind for cleanup: */ + blob_ref = blob; }/* new format carries keyhandle but old format doesn't */
@@ -446,8 +450,6 @@ static int tpm2_load_cmd(struct tpm_chip (__be32 *) &buf.data[TPM_HEADER_SIZE]); out: -if (blob != payload->blob) -kfree (blob);tpm_buf_destroy (&buf);if (rc >0 )
Greg Kroah-Hartman
maintainerPATCH 277/554 mmc: sdhci-msm: Avoid early clock doubling during HS400 transition
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sarthak Garg <[email protected]>
commit b1f856b1727c2eaa4be2c6d7cd7a8ed052bbeb87 upstream.
According to the hardware programming guide, the clock frequency must remain below 52MHz during the transition to HS400 mode.
However,in the current implementation, the timing is set to HS400 (a DDR mode) before adjusting the clock. This causes the clock to double prematurely to 104MHz during the transition phase, violating the specification and potentially resulting in CRC errors or CMD timeouts.
This change ensures that clock doubling is avoided during intermediate transitions and is applied only when the card requires a 200MHz clock for HS400 operation.
--- drivers/mmc/host/sdhci-msm.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
drivers/mmc/host/sdhci-msm.c +15 -12
@@ -340,41 +340,43 @@ static void sdhci_msm_v5_variant_writel_writel_relaxed (val, host->ioaddr + offset); } -static unsigned int msm_get_clock_mult_for_bus_mode (struct sdhci_host *host) +static unsigned int msm_get_clock_mult_for_bus_mode (struct sdhci_host *host, +unsigned int clock, +unsigned int timing) { -struct mmc_ios ios = host->mmc->ios;/* * The SDHC requires internal clock frequency to be double the * actual clock that will be set for DDR mode. The controller * uses the faster clock(100/400MHz) for some of its parts and * send the actual required clock (50/200MHz) to the card. */ -if (ios.timing ==MMC_TIMING_UHS_DDR50 || - ios.timing ==MMC_TIMING_MMC_DDR52 || - ios.timing ==MMC_TIMING_MMC_HS400 || +if (timing ==MMC_TIMING_UHS_DDR50 || + timing ==MMC_TIMING_MMC_DDR52 || + (timing ==MMC_TIMING_MMC_HS400 && + clock ==MMC_HS200_MAX_DTR ) || host->flags &SDHCI_HS400_TUNING )return 2 ;return 1 ; }static void msm_set_clock_rate_for_bus_mode (struct sdhci_host *host, -unsigned int clock) +unsigned int clock, +unsigned int timing) {struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host);struct sdhci_msm_host *msm_host =sdhci_pltfm_priv (pltfm_host); -struct mmc_ios curr_ios = host->mmc->ios;struct clk *core_clk = msm_host->bulk_clks[0 ].clk;unsigned long achieved_rate;unsigned int desired_rate;unsigned int mult;int rc; - mult =msm_get_clock_mult_for_bus_mode (host); + mult =msm_get_clock_mult_for_bus_mode (host, clock, timing); desired_rate = clock * mult; rc =dev_pm_opp_set_rate (mmc_dev (host->mmc), desired_rate);if (rc) {pr_err ("%s: Failed to set clock at rate %u at timing %d\n" , -mmc_hostname (host->mmc), desired_rate, curr_ios.timing); +mmc_hostname (host->mmc), desired_rate, timing);return ; }
@@ -393,7 +395,7 @@ static void msm_set_clock_rate_for_bus_m msm_host->clk_rate = desired_rate;pr_debug ("%s: Setting clock at rate %lu at timing %d\n" , -mmc_hostname (host->mmc), achieved_rate, curr_ios.timing); +mmc_hostname (host->mmc), achieved_rate, timing); }/* Platform specific tuning */
@@ -1235,7 +1237,7 @@ static int sdhci_msm_execute_tuning(stru*/ if (host->flags &SDHCI_HS400_TUNING ) {sdhci_msm_hc_select_mode (host); -msm_set_clock_rate_for_bus_mode (host, ios.clock); +msm_set_clock_rate_for_bus_mode (host, ios.clock, ios.timing); host->flags &= ~SDHCI_HS400_TUNING ; }
@@ -1860,6 +1862,7 @@ static void sdhci_msm_set_clock(struct s {struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host);struct sdhci_msm_host *msm_host =sdhci_pltfm_priv (pltfm_host); +struct mmc_ios ios = host->mmc->ios;if (!clock) { host->mmc->actual_clock = msm_host->clk_rate =0 ;
@@ -1868,7 +1871,7 @@ static void sdhci_msm_set_clock(struct ssdhci_msm_hc_select_mode (host); -msm_set_clock_rate_for_bus_mode (host, clock); +msm_set_clock_rate_for_bus_mode (host, ios.clock, ios.timing); out:__sdhci_msm_set_clock (host, clock); }
Greg Kroah-Hartman
maintainerPATCH 278/554 lib/crypto: x86/blake2s: Fix 32-bit arg treated as 64-bit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 2f22115709fc7ebcfa40af3367a508fbbd2f71e9 upstream.
In the C code, the 'inc' argument to the assembly functions blake2s_compress_ssse3() and blake2s_compress_avx512() is declared with type u32, matching blake2s_compress(). The assembly code then reads it from the 64-bit %rcx. However, the ABI doesn't guarantee zero-extension to 64 bits, nor do gcc or clang guarantee it. Therefore, fix these functions to read this argument from the 32-bit %ecx.
In theory, this bug could have caused the wrong 'inc' value to be used, causing incorrect BLAKE2s hashes. In practice, probably not: I've fixed essentially this same bug in many other assembly files too, but there's never been a real report of it having caused a problem. In x86_64, all writes to 32-bit registers are zero-extended to 64 bits. That results in zero-extension in nearly all situations. I've only been able to demonstrate a lack of zero-extension with a somewhat contrived example involving truncation, e.g. when the C code has a u64 variable holding 0x1234567800000040 and passes it as a u32 expecting it to be truncated to 0x40 (64). But that's not what the real code does, of course.
--- arch/x86/crypto/blake2s-core.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/crypto/blake2s-core.S +2 -2
@@ -54,7 +54,7 @@ SYM_FUNC_START(blake2s_compress_ssse3) movdqa ROT16(%rip),%xmm12 movdqa ROR328(%rip),%xmm13 movdqu 0x20(%rdi),%xmm14 - movq %rcx,%xmm15 + movd %ecx,%xmm15 leaq SIGMA+0xa0(%rip),%r8 jmp .Lbeginofloop .align 32
@@ -179,7 +179,7 @@ SYM_FUNC_START(blake2s_compress_avx512) vmovdqu (%rdi),%xmm0 vmovdqu 0x10(%rdi),%xmm1 vmovdqu 0x20(%rdi),%xmm4 - vmovq %rcx,%xmm5 + vmovd %ecx,%xmm5 vmovdqa IV(%rip),%xmm14 vmovdqa IV+16(%rip),%xmm15 jmp .Lblake2s_compress_avx512_mainloop
Greg Kroah-Hartman
maintainerPATCH 279/554 block: rate-limit capacity change info log
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Chen <[email protected]>
commit 3179a5f7f86bcc3acd5d6fb2a29f891ef5615852 upstream.
loop devices under heavy stress-ng loop streessor can trigger many capacity change events in a short time. Each event prints an info message from set_capacity_and_notify(), flooding the console and contributing to soft lockups on slow consoles.
Switch the printk in set_capacity_and_notify() to pr_info_ratelimited() so frequent capacity changes do not spam the log while still reporting occasional changes.
--- block/genhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/genhd.c +1 -1
@@ -83,7 +83,7 @@ bool set_capacity_and_notify(struct gend (disk->flags & GENHD_FL_HIDDEN))return false; -pr_info ("%s: detected capacity change from %lld to %lld\n" , +pr_info_ratelimited ("%s: detected capacity change from %lld to %lld\n" , disk->disk_name, capacity, size);/*
Greg Kroah-Hartman
maintainerPATCH 280/554 floppy: fix for PAGE_SIZE != 4KB
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rene Rebe <[email protected]>
commit 82d20481024cbae2ea87fe8b86d12961bfda7169 upstream.
For years I wondered why the floppy driver does not just work on sparc64, e.g:
root@SUNW_375_0066:# disktype /dev/fd0 disktype: Can't open /dev/fd0: No such device or address
[ 525.341906] disktype: attempt to access beyond end of device fd0: rw=0, sector=0, nr_sectors = 16 limit=8 [ 525.341991] floppy: error 10 while reading block 0
Turns out floppy.c __floppy_read_block_0 tries to read one page for the first test read to determine the disk size and thus fails if that is greater than 4k. Adjust minimum MAX_DISK_SIZE to PAGE_SIZE to fix floppy on sparc64 and likely all other PAGE_SIZE != 4KB configs.
--- drivers/block/floppy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/floppy.c +1 -1
@@ -331,7 +331,7 @@ static bool initialized;* This default is used whenever the current disk size is unknown. * [Now it is rather a minimum] */ -#define MAX_DISK_SIZE 4/* 3984 */ +#define MAX_DISK_SIZE (PAGE_SIZE / 1024)/* * globals used by 'result()'
Greg Kroah-Hartman
maintainerPATCH 281/554 fs/ntfs3: fix mount failure for sparse runs in run_unpack()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <[email protected]>
commit 801f614ba263cb37624982b27b4c82f3c3c597a9 upstream.
Some NTFS volumes failed to mount because sparse data runs were not handled correctly during runlist unpacking. The code performed arithmetic on the special SPARSE_LCN64 marker, leading to invalid LCN values and mount errors.
Add an explicit check for the case described above, marking the run as sparse without applying arithmetic.
--- fs/ntfs3/run.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/ntfs3/run.c +5 -1
@@ -937,8 +937,12 @@ int run_unpack(struct runs_tree *run, stif (!dlcn)return -EINVAL ; -if (check_add_overflow (prev_lcn, dlcn, &lcn)) +/* Check special combination: 0 + SPARSE_LCN64. */ +if (!prev_lcn && dlcn ==SPARSE_LCN64 ) { + lcn =SPARSE_LCN64 ; + }else if (check_add_overflow (prev_lcn, dlcn, &lcn)) {return -EINVAL ; + } prev_lcn = lcn; }else return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 282/554 ktest.pl: Fix uninitialized var in config-bisect.pl
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit d3042cbe84a060b4df764eb6c5300bbe20d125ca upstream.
The error path of copying the old config used the wrong variable in the error message:
$ mkdir /tmp/build $ ./tools/testing/ktest/config-bisect.pl -b /tmp/build config-good /tmp/config-bad $ chmod 0 /tmp/build $ ./tools/testing/ktest/config-bisect.pl -b /tmp/build config-good /tmp/config-bad good cp /tmp/build//.config config-good.tmp ... [0 seconds] FAILED! Use of uninitialized value $config in concatenation (.) or string at ./tools/testing/ktest/config-bisect.pl line 744. failed to copy to config-good.tmp
When it should have shown:
failed to copy /tmp/build//.config to config-good.tmp
--- tools/testing/ktest/config-bisect.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/ktest/config-bisect.pl +2 -2
@@ -741,9 +741,9 @@ if ($start) { die "Can not find file $bad\n"; } if ($val eq "good") { - run_command "cp $output_config $good" or die "failed to copy $config to $good\n"; + run_command "cp $output_config $good" or die "failed to copy $output_config to $good\n"; } elsif ($val eq "bad") { - run_command "cp $output_config $bad" or die "failed to copy $config to $bad\n"; + run_command "cp $output_config $bad" or die "failed to copy $output_config to $bad\n"; } }
Greg Kroah-Hartman
maintainerPATCH 283/554 ext4: xattr: fix null pointer deref in ext4_raw_inode()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karina Yankevich <[email protected]>
commit b97cb7d6a051aa6ebd57906df0e26e9e36c26d14 upstream.
If ext4_get_inode_loc() fails (e.g. if it returns -EFSCORRUPTED), iloc.bh will remain set to NULL. Since ext4_xattr_inode_dec_ref_all() lacks error checking, this will lead to a null pointer dereference in ext4_raw_inode(), called right after ext4_get_inode_loc().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Message-ID: <[email protected]>
--- fs/ext4/xattr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/ext4/xattr.c +5 -1
@@ -1138,7 +1138,11 @@ ext4_xattr_inode_dec_ref_all(handle_t *hif (block_csum) end = (void *)bh->b_data + bh->b_size;else { -ext4_get_inode_loc (parent, &iloc); + err =ext4_get_inode_loc (parent, &iloc); +if (err) { +EXT4_ERROR_INODE (parent,"parent inode loc (error %d)" , err); +return ; + } end = (void *)ext4_raw_inode (&iloc) +EXT4_SB (parent->i_sb)->s_inode_size; }
Greg Kroah-Hartman
maintainerPATCH 284/554 ext4: clear i_state_flags when alloc inode
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haibo Chen <[email protected]>
commit 4091c8206cfd2e3bb529ef260887296b90d9b6a2 upstream.
i_state_flags used on 32-bit archs, need to clear this flag when alloc inode.
Find this issue when umount ext4, sometimes track the inode as orphan accidently, cause ext4 mesg dump.
Message-ID: <[email protected]>
--- fs/ext4/ialloc.c | 1 - fs/ext4/inode.c | 1 - fs/ext4/super.c | 1 + 3 files changed, 1 insertion(+), 2 deletions(-)
fs/ext4/ialloc.c +0 -1
@@ -1301,7 +1301,6 @@ got: sizeof(gen)); } -ext4_clear_state_flags (ei);/* Only relevant on 32-bit archs */ ext4_set_inode_state (inode,EXT4_STATE_NEW ); ei->i_extra_isize = sbi->s_want_extra_isize;
fs/ext4/inode.c +0 -1
@@ -4754,7 +4754,6 @@ struct inode *__ext4_iget(struct super_b ei->i_projid =make_kprojid (&init_user_ns, i_projid);set_nlink (inode,le16_to_cpu (raw_inode->i_links_count)); -ext4_clear_state_flags (ei);/* Only relevant on 32-bit archs */ ei->i_inline_off =0 ; ei->i_dir_start_lookup =0 ; ei->i_dtime =le32_to_cpu (raw_inode->i_dtime);
fs/ext4/super.c +1 -0
@@ -1300,6 +1300,7 @@ static struct inode *ext4_alloc_inode(stinode_set_iversion (&ei->vfs_inode,1 ); ei->i_flags =0 ; +ext4_clear_state_flags (ei);/* Only relevant on 32-bit archs */ spin_lock_init (&ei->i_raw_lock);INIT_LIST_HEAD (&ei->i_prealloc_list);atomic_set (&ei->i_prealloc_active,0 );
Greg Kroah-Hartman
maintainerPATCH 285/554 ext4: fix incorrect group number assertion in mb_check_buddy
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongjian Sun <[email protected]>
commit 3f7a79d05c692c7cfec70bf104b1b3c3d0ce6247 upstream.
When the MB_CHECK_ASSERT macro is enabled, an assertion failure can occur in __mb_check_buddy when checking preallocated blocks (pa) in a block group:
Assertion failure in mb_free_blocks() : "groupnr == e4b->bd_group"
This happens when a pa at the very end of a block group (e.g., pa_pstart=32765, pa_len=3 in a group of 32768 blocks) becomes exhausted - its pa_pstart is advanced by pa_len to 32768, which lies in the next block group. If this exhausted pa (with pa_len == 0) is still in the bb_prealloc_list during the buddy check, the assertion incorrectly flags it as belonging to the wrong group. A possible sequence is as follows:
ext4_mb_new_blocks
ext4_mb_release_context
pa->pa_pstart += EXT4_C2B(sbi, ac->ac_b_ex.fe_len)
pa->pa_len -= ac->ac_b_ex.fe_len
__mb_check_buddy
for each pa in group
ext4_get_group_no_and_offset
MB_CHECK_ASSERT(groupnr == e4b->bd_group)To fix this, we modify the check to skip block group validation for exhausted preallocations (where pa_len == 0). Such entries are in a transitional state and will be removed from the list soon, so they should not trigger an assertion. This change prevents the false positive while maintaining the integrity of the checks for active allocations.
Message-ID: <[email protected]>
--- fs/ext4/mballoc.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/mballoc.c +2 -0
@@ -767,6 +767,8 @@ static void __mb_check_buddy(struct ext4ext4_group_t groupnr;struct ext4_prealloc_space *pa; pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list); +if (!pa->pa_len) +continue ;ext4_get_group_no_and_offset (sb, pa->pa_pstart, &groupnr, &k);MB_CHECK_ASSERT (groupnr == e4b->bd_group);for (i =0 ; i < pa->pa_len; i++)
Greg Kroah-Hartman
maintainerPATCH 286/554 ext4: align max orphan file size with e2fsprogs limit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 7c11c56eb32eae96893eebafdbe3decadefe88ad upstream.
Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big") limits the maximum supported orphan file size to 8 << 20.
However, in e2fsprogs, the orphan file size is set to 32–512 filesystem blocks when creating a filesystem.
With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger than the kernel allows, so mount prints an error and fails:
EXT4-fs (vdb): orphan file too big: 8650752
EXT4-fs (vdb): mount failed
To prevent this issue and allow previously created 64KB filesystems to mount, we updates the maximum allowed orphan file size in the kernel to 512 filesystem blocks.
Message-ID: <[email protected]>
--- fs/ext4/orphan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/ext4/orphan.c +3 -1
@@ -8,6 +8,8 @@#include "ext4.h" #include "ext4_jbd2.h" +#define EXT4_MAX_ORPHAN_FILE_BLOCKS 512 +static int ext4_orphan_file_add (handle_t *handle,struct inode *inode) {int i, j, start;
@@ -589,7 +591,7 @@ int ext4_init_orphan_info(struct super_b* consuming absurd amounts of memory when pinning blocks of orphan * file in memory. */ -if (inode->i_size >8 <<20 ) { +if (inode->i_size > (EXT4_MAX_ORPHAN_FILE_BLOCKS << inode->i_blkbits)) {ext4_msg (sb,KERN_ERR ,"orphan file too big: %llu" , (unsigned long long )inode->i_size); ret = -EFSCORRUPTED ;
Greg Kroah-Hartman
maintainerPATCH 287/554 jbd2: use a weaker annotation in journal handling
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Byungchul Park <[email protected]>
commit 40a71b53d5a6d4ea17e4d54b99b2ac03a7f5e783 upstream.
jbd2 journal handling code doesn't want jbd2_might_wait_for_commit() to be placed between start_this_handle() and stop_this_handle(). So it marks the region with rwsem_acquire_read() and rwsem_release().
However, the annotation is too strong for that purpose. We don't have to use more than try lock annotation for that.
rwsem_acquire_read() implies:
1. might be a waiter on contention of the lock.
2. enter to the critical section of the lock.
All we need in here is to act 2, not 1. So trylock version of annotation is sufficient for that purpose. Now that dept partially relies on lockdep annotaions, dept interpets rwsem_acquire_read() as a potential wait and might report a deadlock by the wait.
Replace it with trylock version of annotation.
Message-ID: <[email protected]>
--- fs/jbd2/transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jbd2/transaction.c +1 -1
@@ -461,7 +461,7 @@ repeat:read_unlock (&journal->j_state_lock); current->journal_info = handle; -rwsem_acquire_read (&journal->j_trans_commit_map,0 ,0 , _THIS_IP_); +rwsem_acquire_read (&journal->j_trans_commit_map,0 ,1 , _THIS_IP_);jbd2_journal_free_transaction (new_transaction);/* * Ensure that no allocations done while the transaction is open are
Greg Kroah-Hartman
maintainerPATCH 288/554 media: v4l2-mem2mem: Fix outdated documentation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
commit 082b86919b7a94de01d849021b4da820a6cb89dc upstream.
Commit cbd9463da1b1 ("media: v4l2-mem2mem: Avoid calling .device_run in v4l2_m2m_job_finish") deferred calls to .device_run() to a work queue to avoid recursive calls when a job is finished right away from .device_run(). It failed to update the v4l2_m2m_job_finish() documentation that still states the function must not be called from .device_run(). Fix it.
--- include/media/v4l2-mem2mem.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/media/v4l2-mem2mem.h +1 -2
@@ -185,8 +185,7 @@ void v4l2_m2m_try_schedule(struct v4l2_m* other instances to take control of the device. * * This function has to be called only after &v4l2_m2m_ops->device_run -* callback has been called on the driver. To prevent recursion, it should -* not be called directly from the &v4l2_m2m_ops->device_run callback though. +* callback has been called on the driver. */ void v4l2_m2m_job_finish (struct v4l2_m2m_dev *m2m_dev,struct v4l2_m2m_ctx *m2m_ctx);
Greg Kroah-Hartman
maintainerPATCH 289/554 usb: usb-storage: Maintain minimal modifications to the bcdDevice range.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Changcheng <[email protected]>
commit 0831269b5f71594882accfceb02638124f88955d upstream.
We cannot determine which models require the NO_ATA_1X and IGNORE_RESIDUE quirks aside from the EL-R12 optical drive device.
--- drivers/usb/storage/unusual_uas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/unusual_uas.h +1 -1
@@ -98,7 +98,7 @@ UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x01 US_FL_NO_ATA_1X),/* Reported-by: Benjamin Tissoires <[email protected]> */ -UNUSUAL_DEV(0x13fd, 0x3940, 0x0309, 0x0309, +UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x0309, "Initio Corporation", "INIC-3069", USB_SC_DEVICE, USB_PR_DEVICE, NULL,
Greg Kroah-Hartman
maintainerPATCH 290/554 media: dvb-usb: dtv5100: fix out-of-bounds in dtv5100_i2c_msg()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
commit b91e6aafe8d356086cc621bc03e35ba2299e4788 upstream.
rlen value is a user-controlled value, but dtv5100_i2c_msg() does not check the size of the rlen value. Therefore, if it is set to a value larger than sizeof(st->data), an out-of-bounds vuln occurs for st->data.
Therefore, we need to add proper range checking to prevent this vuln.
--- drivers/media/usb/dvb-usb/dtv5100.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/usb/dvb-usb/dtv5100.c +5 -0
@@ -55,6 +55,11 @@ static int dtv5100_i2c_msg(struct dvb_us } index = (addr <<8 ) + wbuf[0 ]; +if (rlen >sizeof (st->data)) { +warn ("rlen = %x is too big!\n" , rlen); +return -EINVAL ; + } +memcpy (st->data, rbuf, rlen);msleep (1 );/* avoid I2C errors */ return usb_control_msg(d->udev, pipe, request,
Greg Kroah-Hartman
maintainerPATCH 291/554 media: pvrusb2: Fix incorrect variable used in trace message
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <[email protected]>
commit be440980eace19c035a0745fd6b6e42707bc4f49 upstream.
The pvr2_trace message is reporting an error about control read transfers, however it is using the incorrect variable write_len instead of read_lean. Fix this by using the correct variable read_len.
--- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/pvrusb2/pvrusb2-hdw.c +1 -1
@@ -3617,7 +3617,7 @@ static int pvr2_send_request_ex(struct ppvr2_trace (PVR2_TRACE_ERROR_LEGS ,"Attempted to execute %d byte control-read transfer (limit=%d)" , - write_len,PVR2_CTL_BUFFSIZE ); + read_len,PVR2_CTL_BUFFSIZE );return -EINVAL ; }if ((!write_len) && (!read_len)) {
Greg Kroah-Hartman
maintainerPATCH 292/554 phy: broadcom: bcm63xx-usbh: fix section mismatches
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 356d1924b9a6bc2164ce2bf1fad147b0c37ae085 upstream.
Platform drivers can be probed after their init sections have been discarded (e.g. on probe deferral or manual rebind through sysfs) so the probe function and match table must not live in init.
--- drivers/phy/broadcom/phy-bcm63xx-usbh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/phy/broadcom/phy-bcm63xx-usbh.c +3 -3
@@ -374,7 +374,7 @@ static struct phy *bcm63xx_usbh_phy_xlatreturn of_phy_simple_xlate (dev, args); } -static int __init bcm63xx_usbh_phy_probe (struct platform_device *pdev) +static int bcm63xx_usbh_phy_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;struct bcm63xx_usbh_phy *usbh;
@@ -431,7 +431,7 @@ static int __init bcm63xx_usbh_phy_probereturn 0 ; } -static const struct of_device_id bcm63xx_usbh_phy_ids[]__initconst = { +static const struct of_device_id bcm63xx_usbh_phy_ids[] = { { .compatible ="brcm,bcm6318-usbh-phy" , .data = &usbh_bcm6318 }, { .compatible ="brcm,bcm6328-usbh-phy" , .data = &usbh_bcm6328 }, { .compatible ="brcm,bcm6358-usbh-phy" , .data = &usbh_bcm6358 },
@@ -442,7 +442,7 @@ static const struct of_device_id bcm63xx };MODULE_DEVICE_TABLE (of, bcm63xx_usbh_phy_ids); -static struct platform_driver bcm63xx_usbh_phy_driver__refdata = { +static struct platform_driver bcm63xx_usbh_phy_driver = { .driver = { .name ="bcm63xx-usbh-phy" , .of_match_table = bcm63xx_usbh_phy_ids,
Greg Kroah-Hartman
maintainerPATCH 293/554 USB: lpc32xx_udc: Fix error handling in probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit c84117912bddd9e5d87e68daf182410c98181407 upstream.
lpc32xx_udc_probe() acquires an i2c_client reference through isp1301_get_client() but fails to release it in both error handling paths and the normal removal path. This could result in a reference count leak for the I2C device, preventing proper cleanup and potentially leading to resource exhaustion. Add put_device() to release the reference in the probe failure path and in the remove function.
Calling path: isp1301_get_client() -> of_find_i2c_device_by_node() -> i2c_find_device_by_fwnode(). As comments of i2c_find_device_by_fwnode() says, 'The user must call put_device(&client->dev) once done with the i2c client.'
Found by code review.
--- drivers/usb/gadget/udc/lpc32xx_udc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
drivers/usb/gadget/udc/lpc32xx_udc.c +15 -6
@@ -3025,7 +3025,7 @@ static int lpc32xx_udc_probe(struct plat pdev->dev.dma_mask = &lpc32xx_usbd_dmamask; retval =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 ));if (retval) -return retval; + goto i2c_fail; udc->board = &lpc32xx_usbddata;
@@ -3043,28 +3043,32 @@ static int lpc32xx_udc_probe(struct plat/* Get IRQs */ for (i =0 ; i <4 ; i++) { udc->udp_irq[i] =platform_get_irq (pdev, i); -if (udc->udp_irq[i] <0 ) -return udc->udp_irq[i]; +if (udc->udp_irq[i] <0 ) { + retval = udc->udp_irq[i]; + goto i2c_fail; + } } udc->udp_baseaddr =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (udc->udp_baseaddr)) {dev_err (udc->dev,"IO map failure\n" ); -return PTR_ERR (udc->udp_baseaddr); + retval =PTR_ERR (udc->udp_baseaddr); + goto i2c_fail; }/* Get USB device clock */ udc->usb_slv_clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (udc->usb_slv_clk)) {dev_err (udc->dev,"failed to acquire USB device clock\n" ); -return PTR_ERR (udc->usb_slv_clk); + retval =PTR_ERR (udc->usb_slv_clk); + goto i2c_fail; }/* Enable USB device clock */ retval =clk_prepare_enable (udc->usb_slv_clk);if (retval <0 ) {dev_err (udc->dev,"failed to start USB device clock\n" ); -return retval; + goto i2c_fail; }/* Setup deferred workqueue data */
@@ -3166,6 +3170,8 @@ dma_alloc_fail:dma_free_coherent (&pdev->dev,UDCA_BUFF_SIZE , udc->udca_v_base, udc->udca_p_base); i2c_fail: +if (udc->isp1301_i2c_client) +put_device (&udc->isp1301_i2c_client->dev);clk_disable_unprepare (udc->usb_slv_clk);dev_err (udc->dev,"%s probe failed, %d\n" , driver_name, retval);
@@ -3191,6 +3197,9 @@ static int lpc32xx_udc_remove(struct pladma_free_coherent (&pdev->dev,UDCA_BUFF_SIZE , udc->udca_v_base, udc->udca_p_base); +if (udc->isp1301_i2c_client) +put_device (&udc->isp1301_i2c_client->dev); +clk_disable_unprepare (udc->usb_slv_clk);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 294/554 usb: phy: fsl-usb: Fix use-after-free in delayed work during device removal
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <[email protected]>
commit 41ca62e3e21e48c2903b3b45e232cf4f2ff7434f upstream.
The delayed work item otg_event is initialized in fsl_otg_conf() and scheduled under two conditions:
1. When a host controller binds to the OTG controller.
2. When the USB ID pin state changes (cable insertion/removal).
A race condition occurs when the device is removed via fsl_otg_remove():
the fsl_otg instance may be freed while the delayed work is still pending or executing. This leads to use-after-free when the work function fsl_otg_event() accesses the already freed memory.
The problematic scenario:
(detach thread) | (delayed work)
fsl_otg_remove() |
kfree(fsl_otg_dev) //FREE| fsl_otg_event()
| og = container_of(...) //USE
| og-> //USEFix this by calling disable_delayed_work_sync() in fsl_otg_remove() before deallocating the fsl_otg structure. This ensures the delayed work is properly canceled and completes execution prior to memory deallocation.
This bug was identified through static analysis.
--- drivers/usb/phy/phy-fsl-usb.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/phy/phy-fsl-usb.c +1 -0
@@ -987,6 +987,7 @@ static int fsl_otg_remove(struct platfor {struct fsl_usb2_platform_data *pdata =dev_get_platdata (&pdev->dev); +disable_delayed_work_sync (&fsl_otg_dev->otg_event);usb_remove_phy (&fsl_otg_dev->phy);free_irq (fsl_otg_dev->irq, fsl_otg_dev);
Greg Kroah-Hartman
maintainerPATCH 295/554 usb: phy: isp1301: fix non-OF device reference imbalance
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit b4b64fda4d30a83a7f00e92a0c8a1d47699609f3 upstream.
A recent change fixing a device reference leak in a UDC driver introduced a potential use-after-free in the non-OF case as the isp1301_get_client() helper only increases the reference count for the returned I2C device in the OF case.
Increment the reference count also for non-OF so that the caller can decrement it unconditionally.
Note that this is inherently racy just as using the returned I2C device is since nothing is preventing the PHY driver from being unbound while in use.
--- drivers/usb/phy/phy-isp1301.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/usb/phy/phy-isp1301.c +6 -1
@@ -152,7 +152,12 @@ struct i2c_client *isp1301_get_client(streturn client;/* non-DT: only one ISP1301 chip supported */ -return isp1301_i2c_client; +if (isp1301_i2c_client) { +get_device (&isp1301_i2c_client->dev); +return isp1301_i2c_client; + } + +return NULL ; }EXPORT_SYMBOL_GPL (isp1301_get_client);
Greg Kroah-Hartman
maintainerPATCH 296/554 usb: dwc3: of-simple: fix clock resource leak in dwc3_of_simple_probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit 3b4961313d31e200c9e974bb1536cdea217f78b5 upstream.
When clk_bulk_prepare_enable() fails, the error path jumps to err_resetc_assert, skipping clk_bulk_put_all() and leaking the clock references acquired by clk_bulk_get_all().
Add err_clk_put_all label to properly release clock resources in all error paths.
Found via static analysis and code review.
--- drivers/usb/dwc3/dwc3-of-simple.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/dwc3/dwc3-of-simple.c +4 -3
@@ -71,11 +71,11 @@ static int dwc3_of_simple_probe(struct p simple->num_clocks = ret; ret =clk_bulk_prepare_enable (simple->num_clocks, simple->clks);if (ret) - goto err_resetc_assert; + goto err_clk_put_all; ret =of_platform_populate (np,NULL ,NULL , dev);if (ret) - goto err_clk_put; + goto err_clk_disable;pm_runtime_set_active (dev);pm_runtime_enable (dev);
@@ -83,8 +83,9 @@ static int dwc3_of_simple_probe(struct preturn 0 ; -err_clk_put: +err_clk_disable:clk_bulk_disable_unprepare (simple->num_clocks, simple->clks); +err_clk_put_all:clk_bulk_put_all (simple->num_clocks, simple->clks); err_resetc_assert:
Greg Kroah-Hartman
maintainerPATCH 297/554 usb: renesas_usbhs: Fix a resource leak in usbhs_pipe_malloc()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 36cc7e09df9e43db21b46519b740145410dd9f4a upstream.
usbhsp_get_pipe() set pipe's flags to IS_USED. In error paths, usbhsp_put_pipe() is required to clear pipe's flags to prevent pipe exhaustion.
--- drivers/usb/renesas_usbhs/pipe.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/renesas_usbhs/pipe.c +2 -0
@@ -713,11 +713,13 @@ struct usbhs_pipe *usbhs_pipe_malloc(str/* make sure pipe is not busy */ ret =usbhsp_pipe_barrier (pipe);if (ret <0 ) { +usbhsp_put_pipe (pipe);dev_err (dev,"pipe setup failed %d\n" ,usbhs_pipe_number (pipe));return NULL ; }if (usbhsp_setup_pipecfg (pipe, is_host, dir_in, &pipecfg)) { +usbhsp_put_pipe (pipe);dev_err (dev,"can't setup pipe\n" );return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 298/554 char: applicom: fix NULL pointer dereference in ac_ioctl
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <[email protected]>
commit 82d12088c297fa1cef670e1718b3d24f414c23f7 upstream.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
In ac_ioctl, the validation of IndexCard and the check for a valid RamIO pointer are skipped when cmd is 6. However, the function unconditionally executes readb(apbs[IndexCard].RamIO + VERS) at the end.
If cmd is 6, IndexCard may reference a board that does not exist (where RamIO is NULL), leading to a NULL pointer dereference.
Fix this by skipping the readb access when cmd is 6, as this command is a global information query and does not target a specific board context.
--- drivers/char/applicom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/char/applicom.c +4 -1
@@ -836,7 +836,10 @@ static long ac_ioctl(struct file *file, ret = -ENOTTY ;break ; } - Dummy =readb (apbs[IndexCard].RamIO +VERS ); + +if (cmd !=6 ) + Dummy =readb (apbs[IndexCard].RamIO +VERS ); +kfree (adgl);mutex_unlock (&ac_mutex);return ret;
Greg Kroah-Hartman
maintainerPATCH 299/554 intel_th: Fix error handling in intel_th_output_open
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 6d5925b667e4ed9e77c8278cc215191d29454a3f upstream.
intel_th_output_open() calls bus_find_device_by_devt() which internally increments the device reference count via get_device(), but this reference is not properly released in several error paths. When device driver is unavailable, file operations cannot be obtained, or the driver's open method fails, the function returns without calling put_device(), leading to a permanent device reference count leak. This prevents the device from being properly released and could cause resource exhaustion over time.
Found by code review.
--- drivers/hwtracing/intel_th/core.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/hwtracing/intel_th/core.c +15 -5
@@ -810,13 +810,17 @@ static int intel_th_output_open(struct iint err; dev =bus_find_device_by_devt (&intel_th_bus, inode->i_rdev); -if (!dev || !dev->driver) -return -ENODEV ; +if (!dev || !dev->driver) { + err = -ENODEV ; + goto out_no_device; + } thdrv =to_intel_th_driver (dev->driver); fops =fops_get (thdrv->fops); -if (!fops) -return -ENODEV ; +if (!fops) { + err = -ENODEV ; + goto out_put_device; + }replace_fops (file, fops);
@@ -824,10 +828,16 @@ static int intel_th_output_open(struct iif (file->f_op->open) { err = file->f_op->open (inode, file); -return err; +if (err) + goto out_put_device; }return 0 ; + +out_put_device: +put_device (dev); +out_no_device: +return err; }static const struct file_operations intel_th_output_fops = {
Greg Kroah-Hartman
maintainerPATCH 300/554 cpufreq: nforce2: fix reference count leak in nforce2
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit 9600156bb99852c216a2128cdf9f114eb67c350f upstream.
There are two reference count leaks in this driver:
1. In nforce2_fsb_read(): pci_get_subsys() increases the reference count of the PCI device, but pci_dev_put() is never called to release it, thus leaking the reference.
2. In nforce2_detect_chipset(): pci_get_subsys() gets a reference to the nforce2_dev which is stored in a global variable, but the reference is never released when the module is unloaded.
Fix both by:
- Adding pci_dev_put(nforce2_sub5) in nforce2_fsb_read() after reading the configuration.
- Adding pci_dev_put(nforce2_dev) in nforce2_exit() to release the global device reference.
Found via static analysis.
--- drivers/cpufreq/cpufreq-nforce2.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cpufreq-nforce2.c +3 -0
@@ -145,6 +145,8 @@ static unsigned int nforce2_fsb_read(intpci_read_config_dword (nforce2_sub5,NFORCE2_BOOTFSB , &fsb); fsb /=1000000 ; +pci_dev_put (nforce2_sub5); +/* Check if PLL register is already set */ pci_read_config_byte (nforce2_dev,NFORCE2_PLLENABLE , (u8 *)&temp);
@@ -432,6 +434,7 @@ static int __init nforce2_init(void) static void __exit nforce2_exit(void) {cpufreq_unregister_driver (&nforce2_driver); +pci_dev_put (nforce2_dev); }module_init (nforce2_init);
Greg Kroah-Hartman
maintainerPATCH 301/554 scsi: Revert "scsi: qla2xxx: Perform lockless command completion in abort path"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Battersby <[email protected]>
commit b57fbc88715b6d18f379463f48a15b560b087ffe upstream.
This reverts commit 0367076b0817d5c75dfb83001ce7ce5c64d803a9.
The commit being reverted added code to __qla2x00_abort_all_cmds() to call sp->done() without holding a spinlock. But unlike the older code below it, this new code failed to check sp->cmd_type and just assumed TYPE_SRB, which results in a jump to an invalid pointer in target-mode with TYPE_TGT_CMD:
qla2xxx [0000:65:00.0]-d034:8: qla24xx_do_nack_work create sess success
0000000009f7a79b
qla2xxx [0000:65:00.0]-5003:8: ISP System Error - mbx1=1ff5h mbx2=10h
mbx3=0h mbx4=0h mbx5=191h mbx6=0h mbx7=0h.
qla2xxx [0000:65:00.0]-d01e:8: -> fwdump no buffer
qla2xxx [0000:65:00.0]-f03a:8: qla_target(0): System error async event
0x8002 occurred
qla2xxx [0000:65:00.0]-00af:8: Performing ISP error recovery -
ha=0000000058183fda.
BUG: kernel NULL pointer dereference, address: 0000000000000000 PF: supervisor instruction fetch in kernel mode PF: error_code(0x0010) - not-present page PGD 0 P4D 0 Oops: 0010 [#1] SMP CPU: 2 PID: 9446 Comm: qla2xxx_8_dpc Tainted: G O 6.1.133 #1 Hardware name: Supermicro Super Server/X11SPL-F, BIOS 4.2 12/15/2023 RIP: 0010:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. RSP: 0018:ffffc90001f93dc8 EFLAGS: 00010206 RAX: 0000000000000282 RBX: 0000000000000355 RCX: ffff88810d16a000 RDX: ffff88810dbadaa8 RSI: 0000000000080000 RDI: ffff888169dc38c0 RBP: ffff888169dc38c0 R08: 0000000000000001 R09: 0000000000000045 R10: ffffffffa034bdf0 R11: 0000000000000000 R12: ffff88810800bb40 R13: 0000000000001aa8 R14: ffff888100136610 R15: ffff8881070f7400 FS: 0000000000000000(0000) GS:ffff88bf80080000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 000000010c8ff006 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? __die+0x4d/0x8b ? page_fault_oops+0x91/0x180 ? trace_buffer_unlock_commit_regs+0x38/0x1a0 ? exc_page_fault+0x391/0x5e0 ? asm_exc_page_fault+0x22/0x30 __qla2x00_abort_all_cmds+0xcb/0x3e0 [qla2xxx_scst] qla2x00_abort_all_cmds+0x50/0x70 [qla2xxx_scst] qla2x00_abort_isp_cleanup+0x3b7/0x4b0 [qla2xxx_scst] qla2x00_abort_isp+0xfd/0x860 [qla2xxx_scst] qla2x00_do_dpc+0x581/0xa40 [qla2xxx_scst] kthread+0xa8/0xd0 </TASK>
Then commit 4475afa2646d ("scsi: qla2xxx: Complete command early within lock") added the spinlock back, because not having the lock caused a race and a crash. But qla2x00_abort_srb() in the switch below already checks for qla2x00_chip_is_down() and handles it the same way, so the code above the switch is now redundant and still buggy in target-mode. Remove it.
--- drivers/scsi/qla2xxx/qla_os.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/scsi/qla2xxx/qla_os.c +0 -6
@@ -1861,12 +1861,6 @@ __qla2x00_abort_all_cmds(struct qla_qpaifor (cnt =1 ; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt];if (sp) { -if (qla2x00_chip_is_down (vha)) { - req->outstanding_cmds[cnt] =NULL ; - sp->done (sp, res); -continue ; - } -switch (sp->cmd_type) {case TYPE_SRB :qla2x00_abort_srb (qp, sp, res, &flags);
Greg Kroah-Hartman
maintainerPATCH 302/554 scsi: aic94xx: fix use-after-free in device removal path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
commit f6ab594672d4cba08540919a4e6be2e202b60007 upstream.
The asd_pci_remove() function fails to synchronize with pending tasklets before freeing the asd_ha structure, leading to a potential use-after-free vulnerability.
When a device removal is triggered (via hot-unplug or module unload), race condition can occur.
The fix adds tasklet_kill() before freeing the asd_ha structure, ensuring all scheduled tasklets complete before cleanup proceeds.
--- drivers/scsi/aic94xx/aic94xx_init.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/aic94xx/aic94xx_init.c +3 -0
@@ -897,6 +897,9 @@ static void asd_pci_remove(struct pci_deasd_disable_ints (asd_ha); +/* Ensure all scheduled tasklets complete before freeing resources */ +tasklet_kill (&asd_ha->seq.dl_tasklet); +asd_remove_dev_attrs (asd_ha);/* XXX more here as needed */
Greg Kroah-Hartman
maintainerPATCH 303/554 NFSD: use correct reservation type in nfsd4_scsi_fence_client
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dai Ngo <[email protected]>
commit 6f52063db9aabdaabea929b1e998af98c2e8d917 upstream.
The reservation type argument for the pr_preempt call should match the one used in nfsd4_block_get_device_info_scsi.
--- fs/nfsd/blocklayout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/blocklayout.c +2 -1
@@ -410,7 +410,8 @@ nfsd4_scsi_fence_client(struct nfs4_layostruct block_device *bdev = ls->ls_file->nf_file->f_path.mnt->mnt_sb->s_bdev; bdev->bd_disk->fops->pr_ops->pr_preempt (bdev,NFSD_MDS_PR_KEY , -nfsd4_scsi_pr_key (clp),0 , true); +nfsd4_scsi_pr_key (clp), +PR_EXCLUSIVE_ACCESS_REG_ONLY , true); }const struct nfsd4_layout_ops scsi_layout_ops = {
Greg Kroah-Hartman
maintainerPATCH 304/554 scsi: target: Reset t_task_cdb pointer in error case
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Vatoropin <[email protected]>
commit 5053eab38a4c4543522d0c320c639c56a8b59908 upstream.
If allocation of cmd->t_task_cdb fails, it remains NULL but is later dereferenced in the 'err' path.
In case of error, reset NULL t_task_cdb value to point at the default fixed-size buffer.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/target/target_core_transport.c | 1 + 1 file changed, 1 insertion(+)
drivers/target/target_core_transport.c +1 -0
@@ -1492,6 +1492,7 @@ target_cmd_init_cdb(struct se_cmd *cmd,if (scsi_command_size (cdb) >sizeof (cmd->__t_task_cdb)) { cmd->t_task_cdb =kzalloc (scsi_command_size (cdb), gfp);if (!cmd->t_task_cdb) { + cmd->t_task_cdb = &cmd->__t_task_cdb[0 ]; pr_err("Unable to allocate cmd->t_task_cdb" " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", scsi_command_size(cdb),
Greg Kroah-Hartman
maintainerPATCH 305/554 f2fs: invalidate dentry cache on failed whiteout creation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
commit d33f89b34aa313f50f9a512d58dd288999f246b0 upstream.
F2FS can mount filesystems with corrupted directory depth values that get runtime-clamped to MAX_DIR_HASH_DEPTH. When RENAME_WHITEOUT operations are performed on such directories, f2fs_rename performs directory modifications (updating target entry and deleting source entry) before attempting to add the whiteout entry via f2fs_add_link.
If f2fs_add_link fails due to the corrupted directory structure, the function returns an error to VFS, but the partial directory modifications have already been committed to disk. VFS assumes the entire rename operation failed and does not update the dentry cache, leaving stale mappings.
In the error path, VFS does not call d_move() to update the dentry cache. This results in new_dentry still pointing to the old inode (new_inode) which has already had its i_nlink decremented to zero. The stale cache causes subsequent operations to incorrectly reference the freed inode.
This causes subsequent operations to use cached dentry information that no longer matches the on-disk state. When a second rename targets the same entry, VFS attempts to decrement i_nlink on the stale inode, which may already have i_nlink=0, triggering a WARNING in drop_nlink().
Example sequence:
1. First rename (RENAME_WHITEOUT): file2 → file1
- f2fs updates file1 entry on disk (points to inode 8)
- f2fs deletes file2 entry on disk
- f2fs_add_link(whiteout) fails (corrupted directory)
- Returns error to VFS
- VFS does not call d_move() due to error
- VFS cache still has: file1 → inode 7 (stale!)
- inode 7 has i_nlink=0 (already decremented)
2. Second rename: file3 → file1
- VFS uses stale cache: file1 → inode 7
- Tries to drop_nlink on inode 7 (i_nlink already 0)
- WARNING in drop_nlink()
Fix this by explicitly invalidating old_dentry and new_dentry when f2fs_add_link fails during whiteout creation. This forces VFS to refresh from disk on subsequent operations, ensuring cache consistency even when the rename partially succeeds.
Reproducer:
1. Mount F2FS image with corrupted i_current_depth
2. renameat2(file2, file1, RENAME_WHITEOUT)
3. renameat2(file3, file1, 0)
4. System triggers WARNING in drop_nlink()
--- fs/f2fs/namei.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/f2fs/namei.c +4 -2
@@ -1017,9 +1017,11 @@ static int f2fs_rename(struct inode *oldif (whiteout) {set_inode_flag (whiteout,FI_INC_LINK ); err =f2fs_add_link (old_dentry, whiteout); -if (err) +if (err) { +d_invalidate (old_dentry); +d_invalidate (new_dentry); goto put_out_dir; - + }spin_lock (&whiteout->i_lock); whiteout->i_state &= ~I_LINKABLE ;spin_unlock (&whiteout->i_lock);
Greg Kroah-Hartman
maintainerPATCH 306/554 f2fs: fix return value of f2fs_recover_fsync_data()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 01fba45deaddcce0d0b01c411435d1acf6feab7b upstream.
With below scripts, it will trigger panic in f2fs:
mkfs.f2fs -f /dev/vdd
mount /dev/vdd /mnt/f2fs
touch /mnt/f2fs/foo
sync
echo 111 >> /mnt/f2fs/foof2fs_io fsync /mnt/f2fs/foof2fs_io shutdown 2 /mnt/f2fs
umount /mnt/f2fs
mount -o ro,norecovery /dev/vdd /mnt/f2fs or
mount -o ro,disable_roll_forward /dev/vdd /mnt/f2fs
F2FS-fs (vdd): f2fs_recover_fsync_data: recovery fsync data, check_only: 0 F2FS-fs (vdd): Mounted with checkpoint version = 7f5c361f F2FS-fs (vdd): Stopped filesystem due to reason: 0
F2FS-fs (vdd): f2fs_recover_fsync_data: recovery fsync data, check_only: 1 Filesystem f2fs get_tree() didn't set fc->root, returned 1
------------[ cut here ]------------ kernel BUG at fs/super.c:1761! Oops: invalid opcode: 0000 [#1] SMP PTI CPU: 3 UID: 0 PID: 722 Comm: mount Not tainted 6.18.0-rc2+ #721 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:vfs_get_tree.cold+0x18/0x1a Call Trace: <TASK> fc_mount+0x13/0xa0 path_mount+0x34e/0xc50 __x64_sys_mount+0x121/0x150 do_syscall_64+0x84/0x800 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fa6cc126cfe
The root cause is we missed to handle error number returned from f2fs_recover_fsync_data() when mounting image w/ ro,norecovery or ro,disable_roll_forward mount option, result in returning a positive error number to vfs_get_tree(), fix it.
--- fs/f2fs/super.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
fs/f2fs/super.c +9 -5
@@ -4374,11 +4374,15 @@ try_onemore: } }else { err =f2fs_recover_fsync_data (sbi, true); - -if (!f2fs_readonly (sb) && err >0 ) { - err = -EINVAL ; -f2fs_err (sbi,"Need to recover fsync data" ); - goto free_meta; +if (err >0 ) { +if (!f2fs_readonly (sb)) { +f2fs_err (sbi,"Need to recover fsync data" ); + err = -EINVAL ; + goto free_meta; + }else { +f2fs_info (sbi,"drop all fsynced data" ); + err =0 ; + } } }
Greg Kroah-Hartman
maintainerPATCH 307/554 tools/testing/nvdimm: Use per-DIMM device handle
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alison Schofield <[email protected]>
commit f59b701b4674f7955170b54c4167c5590f4714eb upstream.
KASAN reports a global-out-of-bounds access when running these nfit
tests: clear.sh, pmem-errors.sh, pfn-meta-errors.sh, btt-errors.sh, daxdev-errors.sh, and inject-error.sh.
[] BUG: KASAN: global-out-of-bounds in nfit_test_ctl+0x769f/0x7840 [nfit_test] [] Read of size 4 at addr ffffffffc03ea01c by task ndctl/1215
[] The buggy address belongs to the variable:
[] handle+0x1c/0x1df4 [nfit_test]
nfit_test_search_spa() uses handle[nvdimm->id] to retrieve a device handle and triggers a KASAN error when it reads past the end of the handle array. It should not be indexing the handle array at all.
The correct device handle is stored in per-DIMM test data. Each DIMM has a struct nfit_mem that embeds a struct acpi_nfit_memdev that describes the NFIT device handle. Use that device handle here.
--- tools/testing/nvdimm/test/nfit.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/testing/nvdimm/test/nfit.c +6 -1
@@ -672,6 +672,7 @@ static int nfit_test_search_spa(struct n .addr = spa->spa, .region = NULL, }; +struct nfit_mem *nfit_mem;u64 dpa; ret = device_for_each_child(&bus->dev, &ctx,
@@ -689,8 +690,12 @@ static int nfit_test_search_spa(struct n*/ nd_mapping = &nd_region->mapping[nd_region->ndr_mappings -1 ]; nvdimm = nd_mapping->nvdimm; + nfit_mem =nvdimm_provider_data (nvdimm); +if (!nfit_mem) +return -EINVAL ; - spa->devices[0 ].nfit_device_handle = handle[nvdimm->id]; + spa->devices[0 ].nfit_device_handle = +__to_nfit_memdev (nfit_mem)->device_handle; spa->num_nvdimms =1 ; spa->devices[0 ].dpa = dpa;
Greg Kroah-Hartman
maintainerPATCH 308/554 media: vidtv: initialize local pointers upon transfer of memory ownership
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
commit 98aabfe2d79f74613abc2b0b1cef08f97eaf5322 upstream.
vidtv_channel_si_init() creates a temporary list (program, service, event) and ownership of the memory itself is transferred to the PAT/SDT/EIT tables through vidtv_psi_pat_program_assign(), vidtv_psi_sdt_service_assign(), vidtv_psi_eit_event_assign().
The problem here is that the local pointer where the memory ownership transfer was completed is not initialized to NULL. This causes the vidtv_psi_pmt_create_sec_for_each_pat_entry() function to fail, and in the flow that jumps to free_eit, the memory that was freed by vidtv_psi_*_table_destroy() can be accessed again by vidtv_psi_*_event_destroy() due to the uninitialized local pointer, so it is freed once again.
Therefore, to prevent use-after-free and double-free vulnerability, local pointers must be initialized to NULL when transferring memory ownership.
--- drivers/media/test-drivers/vidtv/vidtv_channel.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/media/test-drivers/vidtv/vidtv_channel.c +3 -0
@@ -461,12 +461,15 @@ int vidtv_channel_si_init(struct vidtv_m/* assemble all programs and assign to PAT */ vidtv_psi_pat_program_assign (m->si.pat, programs); + programs =NULL ;/* assemble all services and assign to SDT */ vidtv_psi_sdt_service_assign (m->si.sdt, services); + services =NULL ;/* assemble all events and assign to EIT */ vidtv_psi_eit_event_assign (m->si.eit, events); + events =NULL ; m->si.pmt_secs =vidtv_psi_pmt_create_sec_for_each_pat_entry (m->si.pat, m->pcr_pid);
Greg Kroah-Hartman
maintainerPATCH 309/554 ocfs2: fix kernel BUG in ocfs2_find_victim_chain
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prithvi Tambewagh <[email protected]>
commit 039bef30e320827bac8990c9f29d2a68cd8adb5f upstream.
syzbot reported a kernel BUG in ocfs2_find_victim_chain() because the cl_next_free_rec field of the allocation chain list (next free slot in the chain list) is 0, triggring the BUG_ON(!cl->cl_next_free_rec) condition in ocfs2_find_victim_chain() and panicking the kernel.
To fix this, an if condition is introduced in ocfs2_claim_suballoc_bits(), just before calling ocfs2_find_victim_chain(), the code block in it being executed when either of the following conditions is true:
1. cl_next_free_rec is equal to 0, indicating that there are no free chains in the allocation chain list
2. cl_next_free_rec is greater than cl_count (the total number of chains in the allocation chain list)
Either of them being true is indicative of the fact that there are no chains left for usage.
This is addressed using ocfs2_error(), which prints
the error log for debugging purposes, rather than panicking the kernel.
--- fs/ocfs2/suballoc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/ocfs2/suballoc.c +10 -0
@@ -1923,6 +1923,16 @@ static int ocfs2_claim_suballoc_bits(str } cl = (struct ocfs2_chain_list *) &fe->id2.i_chain; +if (!le16_to_cpu (cl->cl_next_free_rec) || +le16_to_cpu (cl->cl_next_free_rec) >le16_to_cpu (cl->cl_count)) { + status =ocfs2_error (ac->ac_inode->i_sb, +"Chain allocator dinode %llu has invalid next " +"free chain record %u, but only %u total\n" , + (unsigned long long )le64_to_cpu (fe->i_blkno), +le16_to_cpu (cl->cl_next_free_rec), +le16_to_cpu (cl->cl_count)); + goto bail; + } victim =ocfs2_find_victim_chain (cl); ac->ac_chain = victim;
Greg Kroah-Hartman
maintainerPATCH 310/554 platform/chrome: cros_ec_ishtp: Fix UAF after unbinding driver
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <[email protected]>
commit 944edca81e7aea15f83cf9a13a6ab67f711e8abd upstream.
After unbinding the driver, another kthread cros_ec_console_log_work is still accessing the device, resulting an UAF and crash.
The driver doesn't unregister the EC device in .remove() which should shutdown sub-devices synchronously. Fix it.
--- drivers/platform/chrome/cros_ec_ishtp.c | 1 + 1 file changed, 1 insertion(+)
drivers/platform/chrome/cros_ec_ishtp.c +1 -0
@@ -710,6 +710,7 @@ static void cros_ec_ishtp_remove(structcancel_work_sync (&client_data->work_ishtp_reset);cancel_work_sync (&client_data->work_ec_evt); +cros_ec_unregister (client_data->ec_dev);cros_ish_deinit (cros_ish_cl);ishtp_put_device (cl_device); }
Greg Kroah-Hartman
maintainerPATCH 311/554 scs: fix a wrong parameter in __scs_magic
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhichi Lin <[email protected]>
commit 08bd4c46d5e63b78e77f2605283874bbe868ab19 upstream.
__scs_magic() needs a 'void *' variable, but a 'struct task_struct *' is given. 'task_scs(tsk)' is the starting address of the task's shadow call stack, and '__scs_magic(task_scs(tsk))' is the end address of the task's shadow call stack. Here should be '__scs_magic(task_scs(tsk))'.
The user-visible effect of this bug is that when CONFIG_DEBUG_STACK_USAGE is enabled, the shadow call stack usage checking function (scs_check_usage) would scan an incorrect memory range. This could lead to:
1. **Inaccurate stack usage reporting**: The function would calculate wrong usage statistics for the shadow call stack, potentially showing incorrect value in kmsg.
2. **Potential kernel crash**: If the value of __scs_magic(tsk)is greater than that of __scs_magic(task_scs(tsk)), the for loop may access unmapped memory, potentially causing a kernel panic. However, this scenario is unlikely because task_struct is allocated via the slab allocator (which typically returns lower addresses), while the shadow call stack returned by task_scs(tsk) is allocated via vmalloc(which typically returns higher addresses).
However, since this is purely a debugging feature (CONFIG_DEBUG_STACK_USAGE), normal production systems should be not unaffected. The bug only impacts developers and testers who are actively debugging stack usage with this configuration enabled.
--- kernel/scs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/scs.c +1 -1
@@ -121,7 +121,7 @@ static void scs_check_usage(struct task_if (!IS_ENABLED (CONFIG_DEBUG_STACK_USAGE ))return ; -for (p =task_scs (tsk); p <__scs_magic (tsk); ++p) { +for (p =task_scs (tsk); p <__scs_magic (task_scs (tsk)); ++p) {if (!READ_ONCE_NOCHECK (*p))break ; used +=sizeof (*p);
Greg Kroah-Hartman
maintainerPATCH 312/554 parisc: Do not reprogram affinitiy on ASP chip
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit dca7da244349eef4d78527cafc0bf80816b261f5 upstream.
The ASP chip is a very old variant of the GSP chip and is used e.g. in HP 730 workstations. When trying to reprogram the affinity it will crash with a HPMC as the relevant registers don't seem to be at the usual location. Let's avoid the crash by checking the sversion. Also note, that reprogramming isn't necessary either, as the HP730 is a just a single-CPU machine.
--- drivers/parisc/gsc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/parisc/gsc.c +3 -1
@@ -154,7 +154,9 @@ static int gsc_set_affinity_irq(struct i gsc_dev->eim = ((u32 ) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data;/* switch IRQ's for devices below LASI/WAX to other CPU */ -gsc_writel (gsc_dev->eim, gsc_dev->hpa +OFFSET_IAR ); +/* ASP chip (svers 0x70) does not support reprogramming */ +if (gsc_dev->gsc->id.sversion !=0x70 ) +gsc_writel (gsc_dev->eim, gsc_dev->hpa +OFFSET_IAR );irq_data_update_effective_affinity (d, &tmask);
Greg Kroah-Hartman
maintainerPATCH 313/554 libceph: make decode_pool() more resilient against corrupted osdmaps
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit 8c738512714e8c0aa18f8a10c072d5b01c83db39 upstream.
If the osdmap is (maliciously) corrupted such that the encoded length of ceph_pg_pool envelope is less than what is expected for a particular encoding version, out-of-bounds reads may ensue because the only bounds check that is there is based on that length value.
This patch adds explicit bounds checks for each field that is decoded or skipped.
--- net/ceph/osdmap.c | 118 ++++++++++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 65 deletions(-)
net/ceph/osdmap.c +53 -65
@@ -790,51 +790,49 @@ static int decode_pool(void **p, void *eceph_decode_need (p, end, len, bad); pool_end = *p + len; +ceph_decode_need (p, end,4 +4 +4 , bad); pi->type =ceph_decode_8 (p); pi->size =ceph_decode_8 (p); pi->crush_ruleset =ceph_decode_8 (p); pi->object_hash =ceph_decode_8 (p); - pi->pg_num =ceph_decode_32 (p); pi->pgp_num =ceph_decode_32 (p); - *p +=4 +4 ;/* skip lpg* */ - *p +=4 ;/* skip last_change */ - *p +=8 +4 ;/* skip snap_seq, snap_epoch */ +/* lpg*, last_change, snap_seq, snap_epoch */ +ceph_decode_skip_n (p, end,8 +4 +8 +4 , bad);/* skip snaps */ - num =ceph_decode_32 (p); +ceph_decode_32_safe (p, end, num, bad);while (num--) { - *p +=8 ;/* snapid key */ - *p +=1 +1 ;/* versions */ - len =ceph_decode_32 (p); - *p += len; +/* snapid key, pool snap (with versions) */ +ceph_decode_skip_n (p, end,8 +2 , bad); +ceph_decode_skip_string (p, end, bad); } -/* skip removed_snaps */ - num =ceph_decode_32 (p); - *p += num * (8 +8 ); +/* removed_snaps */ +ceph_decode_skip_map (p, end,64 ,64 , bad); +ceph_decode_need (p, end,8 +8 +4 , bad); *p +=8 ;/* skip auid */ pi->flags =ceph_decode_64 (p); *p +=4 ;/* skip crash_replay_interval */ if (ev >=7 ) - pi->min_size =ceph_decode_8 (p); +ceph_decode_8_safe (p, end, pi->min_size, bad);else pi->min_size = pi->size - pi->size /2 ;if (ev >=8 ) - *p +=8 +8 ;/* skip quota_max_* */ +/* quota_max_* */ +ceph_decode_skip_n (p, end,8 +8 , bad);if (ev >=9 ) { -/* skip tiers */ - num =ceph_decode_32 (p); - *p += num *8 ; +/* tiers */ +ceph_decode_skip_set (p, end,64 , bad); +ceph_decode_need (p, end,8 +1 +8 +8 , bad); *p +=8 ;/* skip tier_of */ *p +=1 ;/* skip cache_mode */ - pi->read_tier =ceph_decode_64 (p); pi->write_tier =ceph_decode_64 (p); }else {
@@ -842,86 +840,76 @@ static int decode_pool(void **p, void *e pi->write_tier =-1 ; } -if (ev >=10 ) { -/* skip properties */ - num =ceph_decode_32 (p); -while (num--) { - len =ceph_decode_32 (p); - *p += len;/* key */ - len =ceph_decode_32 (p); - *p += len;/* val */ - } - } +if (ev >=10 ) +/* properties */ +ceph_decode_skip_map (p, end, string, string, bad);if (ev >=11 ) { -/* skip hit_set_params */ - *p +=1 +1 ;/* versions */ - len =ceph_decode_32 (p); - *p += len; +/* hit_set_params (with versions) */ +ceph_decode_skip_n (p, end,2 , bad); +ceph_decode_skip_string (p, end, bad); - *p +=4 ;/* skip hit_set_period */ - *p +=4 ;/* skip hit_set_count */ +/* hit_set_period, hit_set_count */ +ceph_decode_skip_n (p, end,4 +4 , bad); }if (ev >=12 ) - *p +=4 ;/* skip stripe_width */ +/* stripe_width */ +ceph_decode_skip_32 (p, end, bad); -if (ev >=13 ) { - *p +=8 ;/* skip target_max_bytes */ - *p +=8 ;/* skip target_max_objects */ - *p +=4 ;/* skip cache_target_dirty_ratio_micro */ - *p +=4 ;/* skip cache_target_full_ratio_micro */ - *p +=4 ;/* skip cache_min_flush_age */ - *p +=4 ;/* skip cache_min_evict_age */ - } - -if (ev >=14 ) { -/* skip erasure_code_profile */ - len =ceph_decode_32 (p); - *p += len; - } +if (ev >=13 ) +/* target_max_*, cache_target_*, cache_min_* */ +ceph_decode_skip_n (p, end,16 +8 +8 , bad); + +if (ev >=14 ) +/* erasure_code_profile */ +ceph_decode_skip_string (p, end, bad);/* * last_force_op_resend_preluminous, will be overridden if the * map was encoded with RESEND_ON_SPLIT */ if (ev >=15 ) - pi->last_force_request_resend =ceph_decode_32 (p); +ceph_decode_32_safe (p, end, pi->last_force_request_resend, bad);else pi->last_force_request_resend =0 ;if (ev >=16 ) - *p +=4 ;/* skip min_read_recency_for_promote */ +/* min_read_recency_for_promote */ +ceph_decode_skip_32 (p, end, bad);if (ev >=17 ) - *p +=8 ;/* skip expected_num_objects */ +/* expected_num_objects */ +ceph_decode_skip_64 (p, end, bad);if (ev >=19 ) - *p +=4 ;/* skip cache_target_dirty_high_ratio_micro */ +/* cache_target_dirty_high_ratio_micro */ +ceph_decode_skip_32 (p, end, bad);if (ev >=20 ) - *p +=4 ;/* skip min_write_recency_for_promote */ +/* min_write_recency_for_promote */ +ceph_decode_skip_32 (p, end, bad);if (ev >=21 ) - *p +=1 ;/* skip use_gmt_hitset */ +/* use_gmt_hitset */ +ceph_decode_skip_8 (p, end, bad);if (ev >=22 ) - *p +=1 ;/* skip fast_read */ +/* fast_read */ +ceph_decode_skip_8 (p, end, bad); -if (ev >=23 ) { - *p +=4 ;/* skip hit_set_grade_decay_rate */ - *p +=4 ;/* skip hit_set_search_last_n */ - } +if (ev >=23 ) +/* hit_set_grade_decay_rate, hit_set_search_last_n */ +ceph_decode_skip_n (p, end,4 +4 , bad);if (ev >=24 ) { -/* skip opts */ - *p +=1 +1 ;/* versions */ - len =ceph_decode_32 (p); - *p += len; +/* opts (with versions) */ +ceph_decode_skip_n (p, end,2 , bad); +ceph_decode_skip_string (p, end, bad); }if (ev >=25 ) - pi->last_force_request_resend =ceph_decode_32 (p); +ceph_decode_32_safe (p, end, pi->last_force_request_resend, bad);/* ignore the rest */
Greg Kroah-Hartman
maintainerPATCH 314/554 KVM: x86: WARN if hrtimer callback for periodic APIC timer fires with period=0
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 0ea9494be9c931ddbc084ad5e11fda91b554cf47 upstream.
WARN and don't restart the hrtimer if KVM's callback runs with the guest's APIC timer in periodic mode but with a period of '0', as not advancing the hrtimer's deadline would put the CPU into an infinite loop of hrtimer events. Observing a period of '0' should be impossible, even when the hrtimer is running on a different CPU than the vCPU, as KVM is supposed to cancel the hrtimer before changing (or zeroing) the period, e.g. when switching from periodic to one-shot.
--- arch/x86/kvm/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/lapic.c +1 -1
@@ -2449,7 +2449,7 @@ static enum hrtimer_restart apic_timer_fapic_timer_expired (apic, true); -if (lapic_is_periodic (apic)) { +if (lapic_is_periodic (apic) && !WARN_ON_ONCE (!apic->lapic_timer.period)) {advance_periodic_target_expiration (apic);hrtimer_add_expires_ns (&ktimer->timer, ktimer->period);return HRTIMER_RESTART ;
Greg Kroah-Hartman
maintainerPATCH 315/554 KVM: x86: Explicitly set new periodic hrtimer expiration in apic_timer_fn()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: fuqiang wang <[email protected]>
commit 9633f180ce994ab293ce4924a9b7aaf4673aa114 upstream.
When restarting an hrtimer to emulate a the guest's APIC timer in periodic mode, explicitly set the expiration using the target expiration computed by advance_periodic_target_expiration() instead of adding the period to the existing timer. This will allow making adjustments to the expiration, e.g. to deal with expirations far in the past, without having to implement the same logic in both advance_periodic_target_expiration() and apic_timer_fn().
--- arch/x86/kvm/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/lapic.c +1 -1
@@ -2451,7 +2451,7 @@ static enum hrtimer_restart apic_timer_fif (lapic_is_periodic (apic) && !WARN_ON_ONCE (!apic->lapic_timer.period)) {advance_periodic_target_expiration (apic); -hrtimer_add_expires_ns (&ktimer->timer, ktimer->period); +hrtimer_set_expires (&ktimer->timer, ktimer->target_expiration);return HRTIMER_RESTART ; }else return HRTIMER_NORESTART ;
Greg Kroah-Hartman
maintainerPATCH 316/554 KVM: x86: Fix VM hard lockup after prolonged inactivity with periodic HV timer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: fuqiang wang <[email protected]>
commit 18ab3fc8e880791aa9f7c000261320fc812b5465 upstream.
When advancing the target expiration for the guest's APIC timer in periodic mode, set the expiration to "now" if the target expiration is in the past (similar to what is done in update_target_expiration()). Blindly adding the period to the previous target expiration can result in KVM generating a practically unbounded number of hrtimer IRQs due to programming an expired timer over and over. In extreme scenarios, e.g. if userspace pauses/suspends a VM for an extended duration, this can even cause hard lockups in the host.
Currently, the bug only affects Intel CPUs when using the hypervisor timer (HV timer), a.k.a. the VMX preemption timer. Unlike the software timer, a.k.a. hrtimer, which KVM keeps running even on exits to userspace, the HV timer only runs while the guest is active. As a result, if the vCPU does not run for an extended duration, there will be a huge gap between the target expiration and the current time the vCPU resumes running. Because the target expiration is incremented by only one period on each timer expiration, this leads to a series of timer expirations occurring rapidly after the vCPU/VM resumes.
More critically, when the vCPU first triggers a periodic HV timer expiration after resuming, advancing the expiration by only one period will result in a target expiration in the past. As a result, the delta may be calculated as a negative value. When the delta is converted into an absolute value (tscdeadline is an unsigned u64), the resulting value can overflow what the HV timer is capable of programming. I.e. the large value will exceed the VMX Preemption Timer's maximum bit width of cpu_preemption_timer_multi + 32, and thus cause KVM to switch from the HV timer to the software timer (hrtimers).
After switching to the software timer, periodic timer expiration callbacks may be executed consecutively within a single clock interrupt handler, because hrtimers honors KVM's request for an expiration in the past and immediately re-invokes KVM's callback after reprogramming. And because the interrupt handler runs with IRQs disabled, restarting KVM's hrtimer over and over until the target expiration is advanced to "now" can result in a hard lockup.
E.g. the following hard lockup was triggered in the host when running a Windows VM (only relevant because it used the APIC timer in periodic mode) after resuming the VM from a long suspend (in the host).
NMI watchdog: Watchdog detected hard LOCKUP on cpu 45
...
RIP: 0010:advance_periodic_target_expiration+0x4d/0x80 [kvm] ... RSP: 0018:ff4f88f5d98d8ef0 EFLAGS: 00000046 RAX: fff0103f91be678e RBX: fff0103f91be678e RCX: 00843a7d9e127bcc RDX: 0000000000000002 RSI: 0052ca4003697505 RDI: ff440d5bfbdbd500 RBP: ff440d5956f99200 R08: ff2ff2a42deb6a84 R09: 000000000002a6c0 R10: 0122d794016332b3 R11: 0000000000000000 R12: ff440db1af39cfc0 R13: ff440db1af39cfc0 R14: ffffffffc0d4a560 R15: ff440db1af39d0f8 FS: 00007f04a6ffd700(0000) GS:ff440db1af380000(0000) knlGS:000000e38a3b8000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000d5651feff8 CR3: 000000684e038002 CR4: 0000000000773ee0 PKRU: 55555554 Call Trace: <IRQ> apic_timer_fn+0x31/0x50 [kvm] __hrtimer_run_queues+0x100/0x280 hrtimer_interrupt+0x100/0x210 ? ttwu_do_wakeup+0x19/0x160 smp_apic_timer_interrupt+0x6a/0x130 apic_timer_interrupt+0xf/0x20 </IRQ>
Moreover, if the suspend duration of the virtual machine is not long enough to trigger a hard lockup in this scenario, since commit 98c25ead5eda ("KVM: VMX: Move preemption timer <=> hrtimer dance to common x86"), KVM will continue using the software timer until the guest reprograms the APIC timer in some way. Since the periodic timer does not require frequent APIC timer register programming, the guest may continue to use the software timer in perpetuity.
--- arch/x86/kvm/lapic.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
arch/x86/kvm/lapic.c +23 -5
@@ -1803,15 +1803,33 @@ static void advance_periodic_target_expiktime_t delta;/* -* Synchronize both deadlines to the same time source or -* differences in the periods (caused by differences in the -* underlying clocks or numerical approximation errors) will -* cause the two to drift apart over time as the errors -* accumulate. +* Use kernel time as the time source for both the hrtimer deadline and +* TSC-based deadline so that they stay synchronized. Computing each +* deadline independently will cause the two deadlines to drift apart +* over time as differences in the periods accumulate, e.g. due to +* differences in the underlying clocks or numerical approximation errors. */ apic->lapic_timer.target_expiration =ktime_add_ns (apic->lapic_timer.target_expiration, apic->lapic_timer.period); + +/* +* If the new expiration is in the past, e.g. because userspace stopped +* running the VM for an extended duration, then force the expiration +* to "now" and don't try to play catch-up with the missed events. KVM +* will only deliver a single interrupt regardless of how many events +* are pending, i.e. restarting the timer with an expiration in the +* past will do nothing more than waste host cycles, and can even lead +* to a hard lockup in extreme cases. +*/ +if (ktime_before (apic->lapic_timer.target_expiration, now)) + apic->lapic_timer.target_expiration = now; + +/* +* Note, ensuring the expiration isn't in the past also prevents delta +* from going negative, which could cause the TSC deadline to become +* excessively large due to it an unsigned value. +*/ delta =ktime_sub (apic->lapic_timer.target_expiration, now); apic->lapic_timer.tscdeadline =kvm_read_l1_tsc (apic->vcpu, tscl) +nsec_to_cycles (apic->vcpu, delta);
Greg Kroah-Hartman
maintainerPATCH 317/554 KVM: nSVM: Propagate SVM_EXIT_CR0_SEL_WRITE correctly for LMSW emulation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
commit 5674a76db0213f9db1e4d08e847ff649b46889c0 upstream.
When emulating L2 instructions, svm_check_intercept() checks whether a write to CR0 should trigger a synthesized #VMEXIT with SVM_EXIT_CR0_SEL_WRITE. For MOV-to-CR0, SVM_EXIT_CR0_SEL_WRITE is only triggered if any bit other than CR0.MP and CR0.TS is updated. However, according to the APM (24593—Rev. 3.42—March 2024, Table 15-7):
The LMSW instruction treats the selective CR0-write intercept as a non-selective intercept (i.e., it intercepts regardless of the value being written).
Skip checking the changed bits for x86_intercept_lmsw and always inject SVM_EXIT_CR0_SEL_WRITE.
--- arch/x86/kvm/svm/svm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
arch/x86/kvm/svm/svm.c +9 -9
@@ -4214,20 +4214,20 @@ static int svm_check_intercept(struct kv INTERCEPT_SELECTIVE_CR0)))break ; - cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK ; - val = info->src_val & ~SVM_CR0_SELECTIVE_MASK ; - +/* LMSW always triggers INTERCEPT_SELECTIVE_CR0 */ if (info->intercept == x86_intercept_lmsw) { - cr0 &=0xfUL ; - val &=0xfUL ; -/* lmsw can't clear PE - catch this here */ -if (cr0 &X86_CR0_PE ) - val |=X86_CR0_PE ; + icpt_info.exit_code =SVM_EXIT_CR0_SEL_WRITE ; +break ; } +/* +* MOV-to-CR0 only triggers INTERCEPT_SELECTIVE_CR0 if any bit +* other than SVM_CR0_SELECTIVE_MASK is changed. +*/ + cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK ; + val = info->src_val & ~SVM_CR0_SELECTIVE_MASK ;if (cr0 ^ val) icpt_info.exit_code =SVM_EXIT_CR0_SEL_WRITE ; -break ; }case SVM_EXIT_READ_DR0 :
Greg Kroah-Hartman
maintainerPATCH 318/554 KVM: nSVM: Set exit_code_hi to -1 when synthesizing SVM_EXIT_ERR (failed VMRUN)
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit f402ecd7a8b6446547076f4bd24bd5d4dcc94481 upstream.
Set exit_code_hi to -1u as a temporary band-aid to fix a long-standing (effectively since KVM's inception) bug where KVM treats the exit code as a 32-bit value, when in reality it's a 64-bit value. Per the APM, offset 0x70 is a single 64-bit value:
070h 63:0 EXITCODE
And a sane reading of the error values defined in "Table C-1. SVM Intercept Codes" is that negative values use the full 64 bits:
–1 VMEXIT_INVALID Invalid guest state in VMCB.
–2 VMEXIT_BUSYBUSY bit was set in the VMSA
–3 VMEXIT_IDLE_REQUIREDThe sibling thread is not in an idle state -4 VMEXIT_INVALID_PMC Invalid PMC state
And that interpretation is confirmed by testing on Milan and Turin (by setting bits in CR0[63:32] to generate VMEXIT_INVALID on VMRUN).
Furthermore, Xen has treated exitcode as a 64-bit value since HVM support was adding in 2006 (see Xen commit d1bd157fbc ("Big merge the HVM full-virtualisation abstractions.")).
--- arch/x86/kvm/svm/nested.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/nested.c +2 -2
@@ -667,7 +667,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcif (!nested_vmcb_valid_sregs (vcpu, &vmcb12->save) || !nested_vmcb_check_controls (vcpu, &svm->nested.ctl)) { vmcb12->control.exit_code =SVM_EXIT_ERR ; - vmcb12->control.exit_code_hi =0 ; + vmcb12->control.exit_code_hi =-1u ; vmcb12->control.exit_info_1 =0 ; vmcb12->control.exit_info_2 =0 ; goto out;
@@ -698,7 +698,7 @@ out_exit_err: svm->nested.nested_run_pending =0 ; svm->vmcb->control.exit_code =SVM_EXIT_ERR ; - svm->vmcb->control.exit_code_hi =0 ; + svm->vmcb->control.exit_code_hi =-1u ; svm->vmcb->control.exit_info_1 =0 ; svm->vmcb->control.exit_info_2 =0 ;
Greg Kroah-Hartman
maintainerPATCH 319/554 KVM: nSVM: Clear exit_code_hi in VMCB when synthesizing nested VM-Exits
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit da01f64e7470988f8607776aa7afa924208863fb upstream.
Explicitly clear exit_code_hi in the VMCB when synthesizing "normal" nested VM-Exits, as the full exit code is a 64-bit value (spoiler alert), and all exit codes for non-failing VMRUN use only bits 31:0.
--- arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/svm/svm.h | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-)
arch/x86/kvm/svm/svm.c +2 -0
@@ -2496,6 +2496,7 @@ static bool check_selective_cr0_intercepif (cr0 ^ val) { svm->vmcb->control.exit_code =SVM_EXIT_CR0_SEL_WRITE ; + svm->vmcb->control.exit_code_hi =0 ; ret = (nested_svm_exit_handled (svm) ==NESTED_EXIT_DONE ); }
@@ -4288,6 +4289,7 @@ static int svm_check_intercept(struct kvif (static_cpu_has (X86_FEATURE_NRIPS )) vmcb->control.next_rip = info->next_rip; vmcb->control.exit_code = icpt_info.exit_code; + vmcb->control.exit_code_hi =0 ; vmexit =nested_svm_exit_handled (svm); ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED
arch/x86/kvm/svm/svm.h +4 -3
@@ -474,9 +474,10 @@ int nested_svm_vmexit(struct vcpu_svm *sstatic inline int nested_svm_simple_vmexit (struct vcpu_svm *svm,u32 exit_code) { - svm->vmcb->control.exit_code = exit_code; - svm->vmcb->control.exit_info_1 =0 ; - svm->vmcb->control.exit_info_2 =0 ; + svm->vmcb->control.exit_code = exit_code; + svm->vmcb->control.exit_code_hi =0 ; + svm->vmcb->control.exit_info_1 =0 ; + svm->vmcb->control.exit_info_2 =0 ;return nested_svm_vmexit (svm); }
Greg Kroah-Hartman
maintainerPATCH 320/554 tracing: Do not register unsupported perf events
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit ef7f38df890f5dcd2ae62f8dbde191d72f3bebae upstream.
Synthetic events currently do not have a function to register perf events. This leads to calling the tracepoint register functions with a NULL function pointer which triggers:
------------[ cut here ]------------ WARNING: kernel/tracepoint.c:175 at tracepoint_add_func+0x357/0x370, CPU#2: perf/2272 Modules linked in: kvm_intel kvm irqbypass CPU: 2 UID: 0 PID: 2272 Comm: perf Not tainted 6.18.0-ftest-11964-ge022764176fc-dirty #323 PREEMPTLAZY Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 RIP: 0010:tracepoint_add_func+0x357/0x370 Code: 28 9c e8 4c 0b f5 ff eb 0f 4c 89 f7 48 c7 c6 80 4d 28 9c e8 ab 89 f4 ff 31 c0 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc <0f> 0b 49 c7 c6 ea ff ff ff e9 ee fe ff ff 0f 0b e9 f9 fe ff ff 0f RSP: 0018:ffffabc0c44d3c40 EFLAGS: 00010246 RAX: 0000000000000001 RBX: ffff9380aa9e4060 RCX: 0000000000000000 RDX: 000000000000000a RSI: ffffffff9e1d4a98 RDI: ffff937fcf5fd6c8 RBP: 0000000000000001 R08: 0000000000000007 R09: ffff937fcf5fc780 R10: 0000000000000003 R11: ffffffff9c193910 R12: 000000000000000a R13: ffffffff9e1e5888 R14: 0000000000000000 R15: ffffabc0c44d3c78 FS: 00007f6202f5f340(0000) GS:ffff93819f00f000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055d3162281a8 CR3: 0000000106a56003 CR4: 0000000000172ef0 Call Trace: <TASK> tracepoint_probe_register+0x5d/0x90 synth_event_reg+0x3c/0x60 perf_trace_event_init+0x204/0x340 perf_trace_init+0x85/0xd0 perf_tp_event_init+0x2e/0x50 perf_try_init_event+0x6f/0x230 ? perf_event_alloc+0x4bb/0xdc0 perf_event_alloc+0x65a/0xdc0 __se_sys_perf_event_open+0x290/0x9f0 do_syscall_64+0x93/0x7b0 ? entry_SYSCALL_64_after_hwframe+0x76/0x7e ? trace_hardirqs_off+0x53/0xc0 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Instead, have the code return -ENODEV, which doesn't warn and has perf error out with:
# perf record -e synthetic:futex_wait Error: The sys_perf_event_open() syscall returned with 19 (No such device) for event (synthetic:futex_wait). "dmesg | grep -i perf" may provide additional information.
Ideally perf should support synthetic events, but for now just fix the warning. The support can come later.
--- kernel/trace/trace_events.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_events.c +2 -0
@@ -655,6 +655,8 @@ int trace_event_reg(struct trace_event_c#ifdef CONFIG_PERF_EVENTS case TRACE_REG_PERF_REGISTER : +if (!call->class->perf_probe) +return -ENODEV ;return tracepoint_probe_register (call->tp, call->class->perf_probe, call);
Greg Kroah-Hartman
maintainerPATCH 321/554 PM: runtime: Do not clear needs_force_resume with enabled runtime PM
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit 359afc8eb02a518fbdd0cbd462c8c2827c6cbec2 upstream.
Commit 89d9cec3b1e9 ("PM: runtime: Clear power.needs_force_resume in pm_runtime_reinit()") added provisional clearing of power.needs_force_resume to pm_runtime_reinit(), but it is done unconditionally which is a mistake because pm_runtime_reinit() may race with driver probing and removal [1].
To address this, notice that power.needs_force_resume should never be set when runtime PM is enabled and so it only needs to be cleared when runtime PM is disabled, and update pm_runtime_init() to only clear that flag when runtime PM is disabled.
--- drivers/base/power/runtime.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/base/power/runtime.c +12 -10
@@ -1747,16 +1747,18 @@ void pm_runtime_init(struct device *dev)*/ void pm_runtime_reinit (struct device *dev) { -if (!pm_runtime_enabled (dev)) { -if (dev->power.runtime_status ==RPM_ACTIVE ) -pm_runtime_set_suspended (dev); -if (dev->power.irq_safe) { -spin_lock_irq (&dev->power.lock); - dev->power.irq_safe =0 ; -spin_unlock_irq (&dev->power.lock); -if (dev->parent) -pm_runtime_put (dev->parent); - } +if (pm_runtime_enabled (dev)) +return ; + +if (dev->power.runtime_status ==RPM_ACTIVE ) +pm_runtime_set_suspended (dev); + +if (dev->power.irq_safe) { +spin_lock_irq (&dev->power.lock); + dev->power.irq_safe =0 ; +spin_unlock_irq (&dev->power.lock); +if (dev->parent) +pm_runtime_put (dev->parent); }/* * Clear power.needs_force_resume in case it has been set by
Greg Kroah-Hartman
maintainerPATCH 322/554 fsnotify: do not generate ACCESS/MODIFY events on child for special files
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
commit 635bc4def026a24e071436f4f356ea08c0eed6ff upstream.
inotify/fanotify do not allow users with no read access to a file to subscribe to events (e.g. IN_ACCESS/IN_MODIFY), but they do allow the same user to subscribe for watching events on children when the user has access to the parent directory (e.g. /dev).
Users with no read access to a file but with read access to its parent directory can still stat the file and see if it was accessed/modified via atime/mtime change.
The same is not true for special files (e.g. /dev/null). Users will not generally observe atime/mtime changes when other users read/write to special files, only when someone sets atime/mtime via utimensat().
Align fsnotify events with this stat behavior and do not generate ACCESS/MODIFY events to parent watchers on read/write of special files. The events are still generated to parent watchers on utimensat(). This closes some side-channels that could be possibly used for information exfiltration [1].
[1] https://snee.la/pdf/pubs/file-notification-attacks.pdf
--- fs/notify/fsnotify.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/notify/fsnotify.c +8 -1
@@ -224,8 +224,15 @@ int __fsnotify_parent(struct dentry *den/* * Include parent/name in notification either if some notification * groups require parent info or the parent is interested in this event. +* The parent interest in ACCESS/MODIFY events does not apply to special +* files, where read/write are not on the filesystem of the parent and +* events can provide an undesirable side-channel for information +* exfiltration. */ - parent_interested = mask & p_mask &ALL_FSNOTIFY_EVENTS ; + parent_interested = mask & p_mask &ALL_FSNOTIFY_EVENTS && + !(data_type ==FSNOTIFY_EVENT_PATH && +d_is_special (dentry) && + (mask & (FS_ACCESS |FS_MODIFY )));if (parent_needed || parent_interested) {/* When notifying parent, child should be passed as data */ WARN_ON_ONCE (inode !=fsnotify_data_inode (data, data_type));
Greg Kroah-Hartman
maintainerPATCH 323/554 nfsd: Mark variable __maybe_unused to avoid W=1 build break
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit ebae102897e760e9e6bc625f701dd666b2163bd1 upstream.
Clang is not happy about set but (in some cases) unused variable:
fs/nfsd/export.c:1027:17: error: variable 'inode' set but not used [-Werror,-Wunused-but-set-variable]
since it's used as a parameter to dprintk() which might be configured a no-op. To avoid uglifying code with the specific ifdeffery just mark the variable __maybe_unused.
The commit [1], which introduced this behaviour, is quite old and hence the Fixes tag points to the first of the Git era.
--- fs/nfsd/export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/export.c +1 -1
@@ -990,7 +990,7 @@ exp_rootfh(struct net *net, struct auth_ {struct svc_export *exp;struct path path; -struct inode *inode; +struct inode *inode__maybe_unused ;struct svc_fh fh;int err;struct nfsd_net *nn =net_generic (net, nfsd_net_id);
Greg Kroah-Hartman
maintainerPATCH 324/554 svcrdma: return 0 on success from svc_rdma_copy_inline_range
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Rogers <[email protected]>
commit 94972027ab55b200e031059fd6c7a649f8248020 upstream.
The function comment specifies 0 on success and -EINVAL on invalid parameters. Make the tail return 0 after a successful copy loop.
--- net/sunrpc/xprtrdma/svc_rdma_rw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/xprtrdma/svc_rdma_rw.c +1 -1
@@ -808,7 +808,7 @@ static int svc_rdma_copy_inline_range(st offset += page_len; } -return -EINVAL ; +return 0 ; }/**
Greg Kroah-Hartman
maintainerPATCH 325/554 io_uring: fix filename leak in __io_openat_prep()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prithvi Tambewagh <[email protected]>
__io_openat_prep() allocates a struct filename using getname(). However,
for the condition of the file being installed in the fixed file table as well as having O_CLOEXEC flag set, the function returns early. At that point, the request doesn't have REQ_F_NEED_CLEANUP flag set. Due to this, the memory for the newly allocated struct filename is not cleaned up, causing a memory leak.
Fix this by setting the REQ_F_NEED_CLEANUP for the request just after the successful getname() call, so that when the request is torn down, the filename will be cleaned up, along with other resources needing cleanup.
--- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/io_uring.c +1 -1
@@ -4326,13 +4326,13 @@ static int __io_openat_prep(struct io_ki req->open.filename =NULL ;return ret; } + req->flags |=REQ_F_NEED_CLEANUP ; req->open.file_slot =READ_ONCE (sqe->file_index);if (req->open.file_slot && (req->open.how.flags &O_CLOEXEC ))return -EINVAL ; req->open.nofile =rlimit (RLIMIT_NOFILE ); - req->flags |=REQ_F_NEED_CLEANUP ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 326/554 drm/amd/display: Use GFP_ATOMIC in dc_create_plane_state()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 3c41114dcdabb7b25f5bc33273c6db9c7af7f4a7 upstream.
This can get called from an atomic context.
--- drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc_surface.c +1 -1
@@ -104,7 +104,7 @@ void enable_surface_flip_reporting(strucstruct dc_plane_state *dc_create_plane_state (struct dc *dc) {struct dc_plane_state *plane_state =kvzalloc (sizeof (*plane_state), -GFP_KERNEL ); +GFP_ATOMIC );if (NULL == plane_state)return NULL ;
Greg Kroah-Hartman
maintainerPATCH 327/554 amba: tegra-ahb: Fix device leak on SMMU enable
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 500e1368e46928f4b2259612dcabb6999afae2a6 upstream.
Make sure to drop the reference taken to the AHB platform device when looking up its driver data while enabling the SMMU.
Note that holding a reference to a device does not prevent its driver data from going away.
--- drivers/amba/tegra-ahb.c | 1 + 1 file changed, 1 insertion(+)
drivers/amba/tegra-ahb.c +1 -0
@@ -144,6 +144,7 @@ int tegra_ahb_enable_smmu(struct device_if (!dev)return -EPROBE_DEFER ; ahb =dev_get_drvdata (dev); +put_device (dev); val =gizmo_readl (ahb,AHB_ARBITRATION_XBAR_CTRL ); val |=AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE ;gizmo_writel (ahb, val,AHB_ARBITRATION_XBAR_CTRL );
Greg Kroah-Hartman
maintainerPATCH 328/554 soc: qcom: ocmem: fix device leak on lookup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit b5c16ea57b030b8e9428ec726e26219dfe05c3d9 upstream.
Make sure to drop the reference taken to the ocmem platform device when looking up its driver data.
Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference.
Also note that commit 0ff027027e05 ("soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem") fixed the leak in a lookup error path, but the reference is still leaking on success.
--- drivers/soc/qcom/ocmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soc/qcom/ocmem.c +1 -1
@@ -211,9 +211,9 @@ struct ocmem *of_get_ocmem(struct deviceof_node_put (devnode); ocmem =platform_get_drvdata (pdev); +put_device (&pdev->dev);if (!ocmem) {dev_err (dev,"Cannot get ocmem\n" ); -put_device (&pdev->dev);return ERR_PTR (-ENODEV ); }return ocmem;
Greg Kroah-Hartman
maintainerPATCH 329/554 soc: amlogic: canvas: fix device leak on lookup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 32200f4828de9d7e6db379909898e718747f4e18 upstream.
Make sure to drop the reference taken to the canvas platform device when looking up its driver data.
Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference.
Also note that commit 28f851e6afa8 ("soc: amlogic: canvas: add missing put_device() call in meson_canvas_get()") fixed the leak in a lookup error path, but the reference is still leaking on success.
--- drivers/soc/amlogic/meson-canvas.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/soc/amlogic/meson-canvas.c +2 -3
@@ -72,10 +72,9 @@ struct meson_canvas *meson_canvas_get(st* current state, this driver probe cannot return -EPROBE_DEFER */ canvas =dev_get_drvdata (&canvas_pdev->dev); -if (!canvas) { -put_device (&canvas_pdev->dev); +put_device (&canvas_pdev->dev); +if (!canvas)return ERR_PTR (-EINVAL ); - }return canvas; }
Greg Kroah-Hartman
maintainerPATCH 330/554 rpmsg: glink: fix rpmsg device leak
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
commit a53e356df548f6b0e82529ef3cc6070f42622189 upstream.
While testing rpmsg-char interface it was noticed that duplicate sysfs entries are getting created and below warning is noticed.
Reason for this is that we are leaking rpmsg device pointer, setting it null without actually unregistering device.
Any further attempts to unregister fail because rpdev is NULL, resulting in a leak.
Fix this by unregistering rpmsg device before removing its reference from rpmsg channel.
sysfs: cannot create duplicate filename '/devices/platform/soc@0/3700000.remot eproc/remoteproc/remoteproc1/3700000.remoteproc:glink-edge/3700000.remoteproc:
glink-edge.adsp_apps.-1.-1'
[ 114.115347] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:0 Not tainted 6.16.0-rc4 #7 PREEMPT [ 114.115355] Hardware name: Qualcomm Technologies, Inc. Robotics RB3gen2 (DT) [ 114.115358] Workqueue: events qcom_glink_work [ 114.115371] Call trace:8 [ 114.115374] show_stack+0x18/0x24 (C) [ 114.115382] dump_stack_lvl+0x60/0x80 [ 114.115388] dump_stack+0x18/0x24 [ 114.115393] sysfs_warn_dup+0x64/0x80 [ 114.115402] sysfs_create_dir_ns+0xf4/0x120 [ 114.115409] kobject_add_internal+0x98/0x260 [ 114.115416] kobject_add+0x9c/0x108 [ 114.115421] device_add+0xc4/0x7a0 [ 114.115429] rpmsg_register_device+0x5c/0xb0 [ 114.115434] qcom_glink_work+0x4bc/0x820 [ 114.115438] process_one_work+0x148/0x284 [ 114.115446] worker_thread+0x2c4/0x3e0 [ 114.115452] kthread+0x12c/0x204 [ 114.115457] ret_from_fork+0x10/0x20 [ 114.115464] kobject: kobject_add_internal failed for 3700000.remoteproc: glink-edge.adsp_apps.-1.-1 with -EEXIST, don't try to register things with the same name in the same directory. [ 114.250045] rpmsg 3700000.remoteproc:glink-edge.adsp_apps.-1.-1:
device_add failed: -17
--- drivers/rpmsg/qcom_glink_native.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/rpmsg/qcom_glink_native.c +8 -0
@@ -1244,6 +1244,7 @@ static void qcom_glink_destroy_ept(struc {struct glink_channel *channel =to_glink_channel (ept);struct qcom_glink *glink = channel->glink; +struct rpmsg_channel_info chinfo;unsigned long flags;spin_lock_irqsave (&channel->recv_lock, flags);
@@ -1251,6 +1252,13 @@ static void qcom_glink_destroy_ept(strucspin_unlock_irqrestore (&channel->recv_lock, flags);/* Decouple the potential rpdev from the channel */ +if (channel->rpdev) { +strscpy_pad (chinfo.name, channel->name,sizeof (chinfo.name)); + chinfo.src =RPMSG_ADDR_ANY ; + chinfo.dst =RPMSG_ADDR_ANY ; + +rpmsg_unregister_device (glink->dev, &chinfo); + } channel->rpdev =NULL ;qcom_glink_send_close_req (glink, channel);
Greg Kroah-Hartman
maintainerPATCH 331/554 i2c: amd-mp2: fix reference leak in MP2 PCI device
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit a6ee6aac66fb394b7f6e6187c73bdcd873f2d139 upstream.
In i2c_amd_probe(), amd_mp2_find_device() utilizes driver_find_next_device() which internally calls driver_find_device() to locate the matching device. driver_find_device() increments the reference count of the found device by calling get_device(), but amd_mp2_find_device() fails to call put_device() to decrement the reference count before returning. This results in a reference count leak of the PCI device each time i2c_amd_probe() is executed, which may prevent the device from being properly released and cause a memory leak.
Found by code review.
--- drivers/i2c/busses/i2c-amd-mp2-pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-amd-mp2-pci.c +4 -1
@@ -452,13 +452,16 @@ struct amd_mp2_dev *amd_mp2_find_device( {struct device *dev;struct pci_dev *pci_dev; +struct amd_mp2_dev *mp2_dev; dev =driver_find_next_device (&amd_mp2_pci_driver.driver,NULL );if (!dev)return NULL ; pci_dev =to_pci_dev (dev); -return (struct amd_mp2_dev *)pci_get_drvdata (pci_dev); + mp2_dev = (struct amd_mp2_dev *)pci_get_drvdata (pci_dev); +put_device (dev); +return mp2_dev; }EXPORT_SYMBOL_GPL (amd_mp2_find_device);
Greg Kroah-Hartman
maintainerPATCH 332/554 hwmon: (max16065) Use local variable to avoid TOCTOU
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
commit b8d5acdcf525f44e521ca4ef51dce4dac403dab4 upstream.
In max16065_current_show, data->curr_sense is read twice: once for the error check and again for the calculation. Since i2c_smbus_read_byte_data returns negative error codes on failure, if the data changes to an error code between the check and the use, ADC_TO_CURR results in an incorrect calculation.
Read data->curr_sense into a local variable to ensure consistency. Note that data->curr_gain is constant and safe to access directly.
This aligns max16065_current_show with max16065_input_show, which already uses a local variable for the same reason.
--- drivers/hwmon/max16065.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/hwmon/max16065.c +4 -3
@@ -216,12 +216,13 @@ static ssize_t max16065_current_show(str struct device_attribute *da, char *buf) { struct max16065_data *data = max16065_update_device(dev); +int curr_sense = data->curr_sense; -if (unlikely (data->curr_sense <0 )) -return data->curr_sense; +if (unlikely (curr_sense <0 )) +return curr_sense;return sysfs_emit (buf,"%d\n" , -ADC_TO_CURR (data->curr_sense, data->curr_gain)); +ADC_TO_CURR (curr_sense, data->curr_gain)); } static ssize_t max16065_limit_store(struct device *dev,
Greg Kroah-Hartman
maintainerPATCH 333/554 hwmon: (w83791d) Convert macros to functions to avoid TOCTOU
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
commit 670d7ef945d3a84683594429aea6ab2cdfa5ceb4 upstream.
The macro FAN_FROM_REG evaluates its arguments multiple times. When used in lockless contexts involving shared driver data, this leads to Time-of-Check to Time-of-Use (TOCTOU) race conditions, potentially causing divide-by-zero errors.
Convert the macro to a static function. This guarantees that arguments are evaluated only once (pass-by-value), preventing the race conditions.
Additionally, in store_fan_div, move the calculation of the minimum limit inside the update lock. This ensures that the read-modify-write sequence operates on consistent data.
Adhere to the principle of minimal changes by only converting macros that evaluate arguments multiple times and are used in lockless contexts.
--- drivers/hwmon/w83791d.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/hwmon/w83791d.c +11 -6
@@ -218,9 +218,14 @@ static u8 fan_to_reg(long rpm, int div)return clamp_val ((1350000 + rpm * div /2 ) / (rpm * div),1 ,254 ); } -#define FAN_FROM_REG (val, div) ((val) == 0 ? -1 : \ - ((val) == 255 ? 0 : \ - 1350000 / ((val) * (div)))) +static int fan_from_reg (int val,int div) +{ +if (val ==0 ) +return -1 ; +if (val ==255 ) +return 0 ; +return 1350000 / (val * div); +}/* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */ #define TEMP1_FROM_REG (val) ((val) * 1000)
@@ -521,7 +526,7 @@ static ssize_t show_##reg(struct devicestruct w83791d_data *data =w83791d_update_device (dev); \int nr = sensor_attr->index; \return sprintf (buf,"%d\n" , \ -FAN_FROM_REG (data->reg[nr],DIV_FROM_REG (data->fan_div[nr]))); \ +fan_from_reg (data->reg[nr],DIV_FROM_REG (data->fan_div[nr]))); \ }show_fan_reg (fan);
@@ -585,10 +590,10 @@ static ssize_t store_fan_div(struct deviif (err)return err; +mutex_lock (&data->update_lock);/* Save fan_min */ - min =FAN_FROM_REG (data->fan_min[nr],DIV_FROM_REG (data->fan_div[nr])); + min =fan_from_reg (data->fan_min[nr],DIV_FROM_REG (data->fan_div[nr])); -mutex_lock (&data->update_lock); data->fan_div[nr] =div_to_reg (nr, val);switch (nr) {
Greg Kroah-Hartman
maintainerPATCH 334/554 hwmon: (w83l786ng) Convert macros to functions to avoid TOCTOU
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
commit 07272e883fc61574b8367d44de48917f622cdd83 upstream.
The macros FAN_FROM_REG and TEMP_FROM_REG evaluate their arguments multiple times. When used in lockless contexts involving shared driver data, this causes Time-of-Check to Time-of-Use (TOCTOU) race conditions.
Convert the macros to static functions. This guarantees that arguments are evaluated only once (pass-by-value), preventing the race conditions.
Adhere to the principle of minimal changes by only converting macros that evaluate arguments multiple times and are used in lockless contexts.
--- drivers/hwmon/w83l786ng.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/hwmon/w83l786ng.c +18 -8
@@ -77,15 +77,25 @@ FAN_TO_REG(long rpm, int div)return clamp_val ((1350000 + rpm * div /2 ) / (rpm * div),1 ,254 ); } -#define FAN_FROM_REG (val, div) ((val) == 0 ? -1 : \ - ((val) == 255 ? 0 : \ - 1350000 / ((val) * (div)))) +static int fan_from_reg (int val,int div) +{ +if (val ==0 ) +return -1 ; +if (val ==255 ) +return 0 ; +return 1350000 / (val * div); +}/* for temp */ #define TEMP_TO_REG (val) (clamp_val(((val) < 0 ? (val) + 0x100 * 1000 \ : (val)) / 1000, 0, 0xff)) -#define TEMP_FROM_REG (val) (((val) & 0x80 ? \ - (val) - 0x100 : (val)) * 1000) + +static int temp_from_reg (int val) +{ +if (val &0x80 ) +return (val -0x100 ) *1000 ; +return val *1000 ; +}/* * The analog voltage inputs have 8mV LSB. Since the sysfs output is
@@ -281,7 +291,7 @@ static ssize_t show_##reg(struct deviceint nr =to_sensor_dev_attr (attr)->index; \struct w83l786ng_data *data =w83l786ng_update_device (dev); \return sprintf (buf,"%d\n" , \ -FAN_FROM_REG (data->reg[nr],DIV_FROM_REG (data->fan_div[nr]))); \ +fan_from_reg (data->reg[nr],DIV_FROM_REG (data->fan_div[nr]))); \ }show_fan_reg (fan);
@@ -348,7 +358,7 @@ store_fan_div(struct device *dev, struct/* Save fan_min */ mutex_lock (&data->update_lock); - min =FAN_FROM_REG (data->fan_min[nr],DIV_FROM_REG (data->fan_div[nr])); + min =fan_from_reg (data->fan_min[nr],DIV_FROM_REG (data->fan_div[nr])); data->fan_div[nr] =DIV_TO_REG (val);
@@ -410,7 +420,7 @@ show_temp(struct device *dev, struct devint nr = sensor_attr->nr;int index = sensor_attr->index;struct w83l786ng_data *data =w83l786ng_update_device (dev); -return sprintf (buf,"%d\n" ,TEMP_FROM_REG (data->temp[nr][index])); +return sprintf (buf,"%d\n" ,temp_from_reg (data->temp[nr][index])); } static ssize_t
Greg Kroah-Hartman
maintainerPATCH 335/554 i40e: fix scheduling in set_rx_mode
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Przemyslaw Korba <[email protected]>
[ Upstream commit be43abc5514167cc129a8d8e9727b89b8e1d9719 ]
Add service task schedule to set_rx_mode.
In some cases there are error messages printed out in PTP application (ptp4l):
ptp4l[13848.762]: port 1 (ens2f3np3): received SYNC without timestamp ptp4l[13848.825]: port 1 (ens2f3np3): received SYNC without timestamp ptp4l[13848.887]: port 1 (ens2f3np3): received SYNC without timestamp
This happens when service task would not run immediately after set_rx_mode, and we need it for setup tasks. This service task checks, if PTP RX packets are hung in firmware, and propagate correct settings such as multicast address for IEEE 1588 Precision Time Protocol. RX timestamping depends on some of these filters set. Bug happens only with high PTP packets frequency incoming, and not every run since sometimes service task is being ran from a different place immediately after starting ptp4l.
--- drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/i40e/i40e_main.c +1 -0
@@ -2216,6 +2216,7 @@ static void i40e_set_rx_mode(struct net_device *netdev) vsi->flags |=I40E_VSI_FLAG_FILTER_CHANGED ;set_bit (__I40E_MACVLAN_SYNC_PENDING, vsi->back->state); } +i40e_service_event_schedule (vsi->back); }/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 336/554 i40e: Refactor argument of several client notification functions
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Vecera <[email protected]>
[ Upstream commit 54c4664e48eea52f2b296c73ddb8f5629b958678 ]
Commit 0ef2d5afb12d ("i40e: KISS the client interface") simplified the client interface so in practice it supports only one client per i40e netdev. But we have still 2 notification functions that uses as parameter a pointer to VSI of netdevice associated with the client. After the mentioned commit only possible and used VSI is the main (LAN) VSI.
So refactor these functions so they are called with PF pointer argument and the associated VSI (LAN) is taken inside them.
Stable-dep-of: 699428342153 ("i40e: validate ring_len parameter against hardware-specific values")
--- drivers/net/ethernet/intel/i40e/i40e.h | 4 ++-- drivers/net/ethernet/intel/i40e/i40e_client.c | 20 +++++++++---------- drivers/net/ethernet/intel/i40e/i40e_main.c | 12 +++++------ 3 files changed, 17 insertions(+), 19 deletions(-)
drivers/net/ethernet/intel/i40e/i40e.h +2 -2
@@ -1198,8 +1198,8 @@ static inline void i40e_dbg_exit(void) {}int i40e_lan_add_device (struct i40e_pf *pf);int i40e_lan_del_device (struct i40e_pf *pf);void i40e_client_subtask (struct i40e_pf *pf); -void i40e_notify_client_of_l2_param_changes (struct i40e_vsi *vsi); -void i40e_notify_client_of_netdev_close (struct i40e_vsi *vsi,bool reset); +void i40e_notify_client_of_l2_param_changes (struct i40e_pf *pf); +void i40e_notify_client_of_netdev_close (struct i40e_pf *pf,bool reset);void i40e_notify_client_of_vf_enable (struct i40e_pf *pf,u32 num_vfs);void i40e_notify_client_of_vf_reset (struct i40e_pf *pf,u32 vf_id);void i40e_client_update_msix_info (struct i40e_pf *pf);
drivers/net/ethernet/intel/i40e/i40e_client.c +10 -10
@@ -102,25 +102,26 @@ i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len)/** * i40e_notify_client_of_l2_param_changes - call the client notify callback -* @vsi: the VSI with l2 param changes +* @pf: PF device pointer * -* If there is a client to this VSI, call the client +* If there is a client, call its callback **/ -void i40e_notify_client_of_l2_param_changes (struct i40e_vsi *vsi) +void i40e_notify_client_of_l2_param_changes (struct i40e_pf *pf) { -struct i40e_pf *pf = vsi->back;struct i40e_client_instance *cdev = pf->cinst; +struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];struct i40e_params params;if (!cdev || !cdev->client)return ;if (!cdev->client->ops || !cdev->client->ops->l2_param_change) { -dev_dbg (&vsi->back->pdev->dev, +dev_dbg (&pf->pdev->dev,"Cannot locate client instance l2_param_change routine\n" );return ; }if (!test_bit (__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { -dev_dbg (&vsi->back->pdev->dev,"Client is not open, abort l2 param change\n" ); +dev_dbg (&pf->pdev->dev, +"Client is not open, abort l2 param change\n" );return ; }memset (¶ms,0 ,sizeof (params));
@@ -160,20 +161,19 @@ static void i40e_client_release_qvlist(struct i40e_info *ldev)/** * i40e_notify_client_of_netdev_close - call the client close callback -* @vsi: the VSI with netdev closed +* @pf: PF device pointer * @reset: true when close called due to a reset pending * * If there is a client to this netdev, call the client with close **/ -void i40e_notify_client_of_netdev_close (struct i40e_vsi *vsi,bool reset) +void i40e_notify_client_of_netdev_close (struct i40e_pf *pf,bool reset) { -struct i40e_pf *pf = vsi->back;struct i40e_client_instance *cdev = pf->cinst;if (!cdev || !cdev->client)return ;if (!cdev->client->ops || !cdev->client->ops->close) { -dev_dbg (&vsi->back->pdev->dev, +dev_dbg (&pf->pdev->dev,"Cannot locate client instance close routine\n" );return ; }
drivers/net/ethernet/intel/i40e/i40e_main.c +5 -7
@@ -11284,14 +11284,12 @@ static void i40e_service_task(struct work_struct *work)i40e_fdir_reinit_subtask (pf);if (test_and_clear_bit (__I40E_CLIENT_RESET, pf->state)) {/* Client subtask will reopen next time through. */ -i40e_notify_client_of_netdev_close (pf->vsi[pf->lan_vsi], - true); +i40e_notify_client_of_netdev_close (pf, true); }else {i40e_client_subtask (pf);if (test_and_clear_bit (__I40E_CLIENT_L2_CHANGE, pf->state)) -i40e_notify_client_of_l2_param_changes ( - pf->vsi[pf->lan_vsi]); +i40e_notify_client_of_l2_param_changes (pf); }i40e_sync_filters_subtask (pf); }else {
@@ -16263,7 +16261,7 @@ static void i40e_remove(struct pci_dev *pdev)/* Client close must be called explicitly here because the timer * has been stopped. */ -i40e_notify_client_of_netdev_close (pf->vsi[pf->lan_vsi], false); +i40e_notify_client_of_netdev_close (pf, false);i40e_fdir_teardown (pf);
@@ -16529,7 +16527,7 @@ static void i40e_shutdown(struct pci_dev *pdev)/* Client close must be called explicitly here because the timer * has been stopped. */ -i40e_notify_client_of_netdev_close (pf->vsi[pf->lan_vsi], false); +i40e_notify_client_of_netdev_close (pf, false);if (pf->wol_en && (pf->hw_features &I40E_HW_WOL_MC_MAGIC_PKT_WAKE ))i40e_enable_mc_magic_wake (pf);
@@ -16582,7 +16580,7 @@ static int __maybe_unused i40e_suspend(struct device *dev)/* Client close must be called explicitly here because the timer * has been stopped. */ -i40e_notify_client_of_netdev_close (pf->vsi[pf->lan_vsi], false); +i40e_notify_client_of_netdev_close (pf, false);if (pf->wol_en && (pf->hw_features &I40E_HW_WOL_MC_MAGIC_PKT_WAKE ))i40e_enable_mc_magic_wake (pf);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 337/554 i40e: Refactor argument of i40e_detect_recover_hung()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Vecera <[email protected]>
[ Upstream commit 7033ada04e33048c8b33294fecbb0d73f3cd1088 ]
Commit 07d44190a389 ("i40e/i40evf: Detect and recover hung queue scenario") changes i40e_detect_recover_hung() argument type from i40e_pf* to i40e_vsi* to be shareable by both i40e and i40evf. Because the i40evf does not exist anymore and the function is exclusively used by i40e we can revert this change.
Stable-dep-of: 699428342153 ("i40e: validate ring_len parameter against hardware-specific values")
--- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 10 ++++++---- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +1 -1
@@ -11275,7 +11275,7 @@ static void i40e_service_task(struct work_struct *work)return ;if (!test_bit (__I40E_RECOVERY_MODE, pf->state)) { -i40e_detect_recover_hung (pf->vsi[pf->lan_vsi]); +i40e_detect_recover_hung (pf);i40e_sync_filters_subtask (pf);i40e_reset_subtask (pf);i40e_handle_mdd_event (pf);
drivers/net/ethernet/intel/i40e/i40e_txrx.c +6 -4
@@ -867,13 +867,15 @@ u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw)/** * i40e_detect_recover_hung - Function to detect and recover hung_queues -* @vsi: pointer to vsi struct with tx queues +* @pf: pointer to PF struct * -* VSI has netdev and netdev has TX queues. This function is to check each of -* those TX queues if they are hung, trigger recovery by issuing SW interrupt. +* LAN VSI has netdev and netdev has TX queues. This function is to check +* each of those TX queues if they are hung, trigger recovery by issuing +* SW interrupt. **/ -void i40e_detect_recover_hung (struct i40e_vsi *vsi) +void i40e_detect_recover_hung (struct i40e_pf *pf) { +struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];struct i40e_ring *tx_ring =NULL ;struct net_device *netdev;unsigned int i;
drivers/net/ethernet/intel/i40e/i40e_txrx.h +1 -1
@@ -462,7 +462,7 @@ void i40e_free_rx_resources(struct i40e_ring *rx_ring);int i40e_napi_poll (struct napi_struct *napi,int budget);void i40e_force_wb (struct i40e_vsi *vsi,struct i40e_q_vector *q_vector);u32 i40e_get_tx_pending (struct i40e_ring *ring,bool in_sw); -void i40e_detect_recover_hung (struct i40e_vsi *vsi); +void i40e_detect_recover_hung (struct i40e_pf *pf);int __i40e_maybe_stop_tx (struct i40e_ring *tx_ring,int size);bool __i40e_chk_linearize (struct sk_buff *skb); int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 338/554 i40e: validate ring_len parameter against hardware-specific values
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory Herrero <[email protected]>
[ Upstream commit 69942834215323cd9131db557091b4dec43f19c5 ]
The maximum number of descriptors supported by the hardware is hardware-dependent and can be retrieved using i40e_get_max_num_descriptors(). Move this function to a shared header and use it when checking for valid ring_len parameter rather than using hardcoded value.
By fixing an over-acceptance issue, behavior change could be seen where ring_len could now be rejected while configuring rx and tx queues if its size is larger than the hardware-dependent maximum number of descriptors.
--- drivers/net/ethernet/intel/i40e/i40e.h | 11 +++++++++++ drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 12 ------------ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 4 ++-- 3 files changed, 13 insertions(+), 14 deletions(-)
drivers/net/ethernet/intel/i40e/i40e.h +11 -0
@@ -1305,4 +1305,15 @@ static inline u32 i40e_is_tc_mqprio_enabled(struct i40e_pf *pf) return pf->flags & I40E_FLAG_TC_MQPRIO; } +static inline u32 i40e_get_max_num_descriptors (const struct i40e_pf *pf) +{ +const struct i40e_hw *hw = &pf->hw; + +switch (hw->mac.type) { +case I40E_MAC_XL710 : +return I40E_MAX_NUM_DESCRIPTORS_XL710 ; +default : +return I40E_MAX_NUM_DESCRIPTORS ; + } +}#endif /* _I40E_H_ */
drivers/net/ethernet/intel/i40e/i40e_ethtool.c +0 -12
@@ -1918,18 +1918,6 @@ static void i40e_get_drvinfo(struct net_device *netdev, drvinfo->n_priv_flags +=I40E_GL_PRIV_FLAGS_STR_LEN ; } -static u32 i40e_get_max_num_descriptors (struct i40e_pf *pf) -{ -struct i40e_hw *hw = &pf->hw; - -switch (hw->mac.type) { -case I40E_MAC_XL710 : -return I40E_MAX_NUM_DESCRIPTORS_XL710 ; -default : -return I40E_MAX_NUM_DESCRIPTORS ; - } -} -static void i40e_get_ringparam (struct net_device *netdev,struct ethtool_ringparam *ring) {
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +2 -2
@@ -656,7 +656,7 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_id,/* ring_len has to be multiple of 8 */ if (!IS_ALIGNED (info->ring_len,8 ) || - info->ring_len >I40E_MAX_NUM_DESCRIPTORS_XL710 ) { + info->ring_len >i40e_get_max_num_descriptors (pf)) { ret = -EINVAL ; goto error_context; }
@@ -728,7 +728,7 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id,/* ring_len has to be multiple of 32 */ if (!IS_ALIGNED (info->ring_len,32 ) || - info->ring_len >I40E_MAX_NUM_DESCRIPTORS_XL710 ) { + info->ring_len >i40e_get_max_num_descriptors (pf)) { ret = -EINVAL ; goto error_param; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 339/554 iavf: fix off-by-one issues in iavf_config_rss_reg()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kohei Enju <[email protected]>
[ Upstream commit 6daa2893f323981c7894c68440823326e93a7d61 ]
There are off-by-one bugs when configuring RSS hash key and lookup table, causing out-of-bounds reads to memory [1] and out-of-bounds writes to device registers.
Before commit 43a3d9ba34c9 ("i40evf: Allow PF driver to configure RSS"), the loop upper bounds were:
i <= I40E_VFQF_{HKEY,HLUT}_MAX_INDEXwhich is safe since the value is the last valid index.
That commit changed the bounds to:
i <= adapter->rss_{key,lut}_size / 4where rss_{key,lut}_size / 4 is the number of dwords, so the last valid index is (rss_{key,lut}_size / 4) - 1. Therefore, using <= accesses one element past the end.
Fix the issues by using < instead of <=, ensuring we do not exceed the bounds.
[1] KASAN splat about rss_key_size off-by-one
BUG: KASAN: slab-out-of-bounds in iavf_config_rss+0x619/0x800
Read of size 4 at addr ffff888102c50134 by task kworker/u8:6/63
CPU: 0 UID: 0 PID: 63 Comm: kworker/u8:6 Not tainted 6.18.0-rc2-enjuk-tnguy-00378-g3005f5b77652-dirty #156 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: iavf iavf_watchdog_task
Call Trace:
<TASK>
dump_stack_lvl+0x6f/0xb0
print_report+0x170/0x4f3
kasan_report+0xe1/0x1a0
iavf_config_rss+0x619/0x800
iavf_watchdog_task+0x2be7/0x3230
process_one_work+0x7fd/0x1420
worker_thread+0x4d1/0xd40
kthread+0x344/0x660
ret_from_fork+0x249/0x320
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 63:
kasan_save_stack+0x30/0x50
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x7f/0x90
__kmalloc_noprof+0x246/0x6f0
iavf_watchdog_task+0x28fc/0x3230
process_one_work+0x7fd/0x1420
worker_thread+0x4d1/0xd40
kthread+0x344/0x660
ret_from_fork+0x249/0x320
ret_from_fork_asm+0x1a/0x30
The buggy address belongs to the object at ffff888102c50100
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 0 bytes to the right of
allocated 52-byte region [ffff888102c50100, ffff888102c50134)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x102c50
flags: 0x200000000000000(node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000000 ffff8881000418c0 dead000000000122 0000000000000000
raw: 0000000000000000 0000000080200020 00000000f5000000 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888102c50000: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc
ffff888102c50080: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc
>ffff888102c50100: 00 00 00 00 00 00 04 fc fc fc fc fc fc fc fc fc
^
ffff888102c50180: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc
ffff888102c50200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc--- drivers/net/ethernet/intel/iavf/iavf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +2 -2
@@ -1393,11 +1393,11 @@ static int iavf_config_rss_reg(struct iavf_adapter *adapter)u16 i; dw = (u32 *)adapter->rss_key; -for (i =0 ; i <= adapter->rss_key_size /4 ; i++) +for (i =0 ; i < adapter->rss_key_size /4 ; i++)wr32 (hw,IAVF_VFQF_HKEY (i), dw[i]); dw = (u32 *)adapter->rss_lut; -for (i =0 ; i <= adapter->rss_lut_size /4 ; i++) +for (i =0 ; i < adapter->rss_lut_size /4 ; i++)wr32 (hw,IAVF_VFQF_HLUT (i), dw[i]);iavf_flush (hw);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 340/554 crypto: seqiv - Do not use req->iv after crypto_aead_encrypt
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 50fdb78b7c0bcc550910ef69c0984e751cac72fa ]
As soon as crypto_aead_encrypt is called, the underlying request may be freed by an asynchronous completion. Thus dereferencing req->iv after it returns is invalid.
Instead of checking req->iv against info, create a new variable unaligned_info and use it for that purpose instead.
--- crypto/seqiv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
crypto/seqiv.c +5 -3
@@ -51,6 +51,7 @@ static int seqiv_aead_encrypt(struct aead_request *req)struct aead_geniv_ctx *ctx =crypto_aead_ctx (geniv);struct aead_request *subreq =aead_request_ctx (req);crypto_completion_t compl; +bool unaligned_info;void *data;u8 *info;unsigned int ivsize =8 ;
@@ -80,8 +81,9 @@ static int seqiv_aead_encrypt(struct aead_request *req)return err; } -if (unlikely (!IS_ALIGNED ((unsigned long )info, -crypto_aead_alignmask (geniv) +1 ))) { + unaligned_info = !IS_ALIGNED ((unsigned long )info, +crypto_aead_alignmask (geniv) +1 ); +if (unlikely (unaligned_info)) { info =kmemdup (req->iv, ivsize, req->base.flags &CRYPTO_TFM_REQ_MAY_SLEEP ?GFP_KERNEL :GFP_ATOMIC );
@@ -101,7 +103,7 @@ static int seqiv_aead_encrypt(struct aead_request *req)scatterwalk_map_and_copy (info, req->dst, req->assoclen, ivsize,1 ); err =crypto_aead_encrypt (subreq); -if (unlikely (info != req->iv)) +if (unlikely (unaligned_info))seqiv_aead_encrypt_complete2 (req, err);return err; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 341/554 Bluetooth: btusb: revert use of devm_kzalloc in btusb
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphael Pinsonneault-Thibeault <[email protected]>
[ Upstream commit 252714f1e8bdd542025b16321c790458014d6880 ]
This reverts commit 98921dbd00c4e ("Bluetooth: Use devm_kzalloc in btusb.c file").
In btusb_probe(), we use devm_kzalloc() to allocate the btusb data. This ties the lifetime of all the btusb data to the binding of a driver to one interface, INTF. In a driver that binds to other interfaces, ISOC and DIAG, this is an accident waiting to happen.
The issue is revealed in btusb_disconnect(), where calling usb_driver_release_interface(&btusb_driver, data->intf) will have devm free the data that is also being used by the other interfaces of the driver that may not be released yet.
To fix this, revert the use of devm and go back to freeing memory explicitly.
--- drivers/bluetooth/btusb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/bluetooth/btusb.c +9 -3
@@ -3788,7 +3788,7 @@ static int btusb_probe(struct usb_interface *intf,return -ENODEV ; } - data =devm_kzalloc (&intf->dev,sizeof (*data),GFP_KERNEL ); + data =kzalloc (sizeof (*data),GFP_KERNEL );if (!data)return -ENOMEM ;
@@ -3811,8 +3811,10 @@ static int btusb_probe(struct usb_interface *intf, } } -if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) +if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) { +kfree (data);return -ENODEV ; + }if (id->driver_info &BTUSB_AMP ) { data->cmdreq_type =USB_TYPE_CLASS |0x01 ;
@@ -3855,8 +3857,10 @@ static int btusb_probe(struct usb_interface *intf, data->recv_acl = hci_recv_frame; hdev =hci_alloc_dev_priv (priv_size); -if (!hdev) +if (!hdev) { +kfree (data);return -ENOMEM ; + } hdev->bus =HCI_USB ;hci_set_drvdata (hdev, data);
@@ -4104,6 +4108,7 @@ static int btusb_probe(struct usb_interface *intf,if (data->reset_gpio)gpiod_put (data->reset_gpio);hci_free_dev (hdev); +kfree (data);return err; }
@@ -4149,6 +4154,7 @@ static void btusb_disconnect(struct usb_interface *intf) }hci_free_dev (hdev); +kfree (data); }#ifdef CONFIG_PM
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 342/554 net: mdio: aspeed: move reg accessing part into separate functions
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Potin Lai <[email protected]>
[ Upstream commit 737ca352569e744bf753b4522a6f91b120a734f1 ]
Add aspeed_mdio_op() and aseed_mdio_get_data() for register accessing.
aspeed_mdio_op() handles operations, write command to control register, then check and wait operations is finished (bit 31 is cleared).
aseed_mdio_get_data() fetchs the result value of operation from data register.
Stable-dep-of: d1a1a4bade4b ("net: mdio: aspeed: add dummy read to avoid read-after-write issue")
--- drivers/net/mdio/mdio-aspeed.c | 70 ++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 32 deletions(-)
drivers/net/mdio/mdio-aspeed.c +38 -32
@@ -39,34 +39,35 @@ struct aspeed_mdio {void __iomem *base; }; -static int aspeed_mdio_read (struct mii_bus *bus,int addr,int regnum) +static int aspeed_mdio_op (struct mii_bus *bus,u8 st,u8 op,u8 phyad,u8 regad, +u16 data) {struct aspeed_mdio *ctx = bus->priv;u32 ctrl; -u32 data; -int rc; -dev_dbg (&bus->dev,"%s: addr: %d, regnum: %d\n" , __func__, addr, - regnum); - -/* Just clause 22 for the moment */ -if (regnum &MII_ADDR_C45 ) -return -EOPNOTSUPP ; +dev_dbg (&bus->dev,"%s: st: %u op: %u, phyad: %u, regad: %u, data: %u\n" , + __func__, st, op, phyad, regad, data); ctrl =ASPEED_MDIO_CTRL_FIRE - |FIELD_PREP (ASPEED_MDIO_CTRL_ST ,ASPEED_MDIO_CTRL_ST_C22 ) - |FIELD_PREP (ASPEED_MDIO_CTRL_OP ,MDIO_C22_OP_READ ) - |FIELD_PREP (ASPEED_MDIO_CTRL_PHYAD , addr) - |FIELD_PREP (ASPEED_MDIO_CTRL_REGAD , regnum); + |FIELD_PREP (ASPEED_MDIO_CTRL_ST , st) + |FIELD_PREP (ASPEED_MDIO_CTRL_OP , op) + |FIELD_PREP (ASPEED_MDIO_CTRL_PHYAD , phyad) + |FIELD_PREP (ASPEED_MDIO_CTRL_REGAD , regad) + |FIELD_PREP (ASPEED_MDIO_DATA_MIIRDATA , data);iowrite32 (ctrl, ctx->base +ASPEED_MDIO_CTRL ); - rc =readl_poll_timeout (ctx->base +ASPEED_MDIO_CTRL , ctrl, +return readl_poll_timeout (ctx->base +ASPEED_MDIO_CTRL , ctrl, !(ctrl &ASPEED_MDIO_CTRL_FIRE ),ASPEED_MDIO_INTERVAL_US ,ASPEED_MDIO_TIMEOUT_US ); -if (rc <0 ) -return rc; +} + +static int aspeed_mdio_get_data (struct mii_bus *bus) +{ +struct aspeed_mdio *ctx = bus->priv; +int rc; +u32 data; rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_DATA, data, data & ASPEED_MDIO_DATA_IDLE,
@@ -78,31 +79,36 @@ static int aspeed_mdio_read(struct mii_bus *bus, int addr, int regnum)return FIELD_GET (ASPEED_MDIO_DATA_MIIRDATA , data); } -static int aspeed_mdio_write (struct mii_bus *bus,int addr,int regnum,u16 val) +static int aspeed_mdio_read (struct mii_bus *bus,int addr,int regnum) { -struct aspeed_mdio *ctx = bus->priv; -u32 ctrl; +int rc; -dev_dbg (&bus->dev,"%s: addr: %d, regnum: %d, val: 0x%x\n" , - __func__, addr, regnum, val); +dev_dbg (&bus->dev,"%s: addr: %d, regnum: %d\n" , __func__, addr, + regnum);/* Just clause 22 for the moment */ if (regnum &MII_ADDR_C45 )return -EOPNOTSUPP ; - ctrl =ASPEED_MDIO_CTRL_FIRE - |FIELD_PREP (ASPEED_MDIO_CTRL_ST ,ASPEED_MDIO_CTRL_ST_C22 ) - |FIELD_PREP (ASPEED_MDIO_CTRL_OP ,MDIO_C22_OP_WRITE ) - |FIELD_PREP (ASPEED_MDIO_CTRL_PHYAD , addr) - |FIELD_PREP (ASPEED_MDIO_CTRL_REGAD , regnum) - |FIELD_PREP (ASPEED_MDIO_CTRL_MIIWDATA , val); + rc =aspeed_mdio_op (bus,ASPEED_MDIO_CTRL_ST_C22 ,MDIO_C22_OP_READ , + addr, regnum,0 ); +if (rc <0 ) +return rc; -iowrite32 (ctrl, ctx->base +ASPEED_MDIO_CTRL ); +return aspeed_mdio_get_data (bus); +} -return readl_poll_timeout (ctx->base +ASPEED_MDIO_CTRL , ctrl, - !(ctrl &ASPEED_MDIO_CTRL_FIRE ), -ASPEED_MDIO_INTERVAL_US , -ASPEED_MDIO_TIMEOUT_US ); +static int aspeed_mdio_write (struct mii_bus *bus,int addr,int regnum,u16 val) +{ +dev_dbg (&bus->dev,"%s: addr: %d, regnum: %d, val: 0x%x\n" , + __func__, addr, regnum, val); + +/* Just clause 22 for the moment */ +if (regnum &MII_ADDR_C45 ) +return -EOPNOTSUPP ; + +return aspeed_mdio_op (bus,ASPEED_MDIO_CTRL_ST_C22 ,MDIO_C22_OP_WRITE , + addr, regnum, val); }static int aspeed_mdio_probe (struct platform_device *pdev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 343/554 net: mdio: aspeed: add dummy read to avoid read-after-write issue
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacky Chou <[email protected]>
[ Upstream commit d1a1a4bade4b20c0858d0b2f81d2611de055f675 ]
The Aspeed MDIO controller may return incorrect data when a read operation follows immediately after a write. Due to a controller bug, the subsequent read can latch stale data, causing the polling logic to terminate earlier than expected.
To work around this hardware issue, insert a dummy read after each write operation. This ensures that the next actual read returns the correct data and prevents premature polling exit.
This workaround has been verified to stabilize MDIO transactions on affected Aspeed platforms.
--- drivers/net/mdio/mdio-aspeed.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/mdio/mdio-aspeed.c +7 -0
@@ -57,6 +57,13 @@ static int aspeed_mdio_op(struct mii_bus *bus, u8 st, u8 op, u8 phyad, u8 regad,iowrite32 (ctrl, ctx->base +ASPEED_MDIO_CTRL ); +/* Workaround for read-after-write issue. +* The controller may return stale data if a read follows immediately +* after a write. A dummy read forces the hardware to update its +* internal state, ensuring that the next real read returns correct data. +*/ +ioread32 (ctx->base +ASPEED_MDIO_CTRL ); + return readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl, !(ctrl & ASPEED_MDIO_CTRL_FIRE), ASPEED_MDIO_INTERVAL_US,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 344/554 net: openvswitch: Avoid needlessly taking the RTNL on vport destroy
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toke Høiland-Jørgensen <[email protected]>
[ Upstream commit 5498227676303e3ffa9a3a46214af96bc3e81314 ]
The openvswitch teardown code will immediately call ovs_netdev_detach_dev() in response to a NETDEV_UNREGISTER notification. It will then start the dp_notify_work workqueue, which will later end up calling the vport destroy() callback. This callback takes the RTNL to do another ovs_netdev_detach_port(), which in this case is unnecessary. This causes extra pressure on the RTNL, in some cases leading to "unregister_netdevice: waiting for XX to become free" warnings on teardown.
We can straight-forwardly avoid the extra RTNL lock acquisition by checking the device flags before taking the lock, and skip the locking altogether if the IFF_OVS_DATAPATH flag has already been unset.
--- net/openvswitch/vport-netdev.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
net/openvswitch/vport-netdev.c +13 -4
@@ -154,10 +154,19 @@ void ovs_netdev_detach_dev(struct vport *vport)static void netdev_destroy (struct vport *vport) { -rtnl_lock (); -if (netif_is_ovs_port (vport->dev)) -ovs_netdev_detach_dev (vport); -rtnl_unlock (); +/* When called from ovs_db_notify_wq() after a dp_device_event(), the +* port has already been detached, so we can avoid taking the RTNL by +* checking this first. +*/ +if (netif_is_ovs_port (vport->dev)) { +rtnl_lock (); +/* Check again while holding the lock to ensure we don't race +* with the netdev notifier and detach twice. +*/ +if (netif_is_ovs_port (vport->dev)) +ovs_netdev_detach_dev (vport); +rtnl_unlock (); + }call_rcu (&vport->rcu, vport_netdev_free); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 345/554 ip6_gre: make ip6gre_header() robust
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit db5b4e39c4e63700c68a7e65fc4e1f1375273476 ]
Over the years, syzbot found many ways to crash the kernel in ip6gre_header() [1].
This involves team or bonding drivers ability to dynamically change their dev->needed_headroom and/or dev->hard_header_len
In this particular crash mld_newpack() allocated an skb with a too small reserve/headroom, and by the time mld_sendpack() was called, syzbot managed to attach an ip6gre device.
[1]
skbuff: skb_under_panic: text:ffffffff8a1d69a8 len:136 put:40 head:ffff888059bc7000 data:ffff888059bc6fe8 tail:0x70 end:0x6c0 dev:team0
------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:213 ! <TASK> skb_under_panic net/core/skbuff.c:223 [inline] skb_push+0xc3/0xe0 net/core/skbuff.c:2641 ip6gre_header+0xc8/0x790 net/ipv6/ip6_gre.c:1371 dev_hard_header include/linux/netdevice.h:3436 [inline] neigh_connected_output+0x286/0x460 net/core/neighbour.c:1618 neigh_output include/net/neighbour.h:556 [inline] ip6_finish_output2+0xfb3/0x1480 net/ipv6/ip6_output.c:136 __ip6_finish_output net/ipv6/ip6_output.c:-1 [inline] ip6_finish_output+0x234/0x7d0 net/ipv6/ip6_output.c:220 NF_HOOK_COND include/linux/netfilter.h:307 [inline] ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247 NF_HOOK+0x9e/0x380 include/linux/netfilter.h:318 mld_sendpack+0x8d4/0xe60 net/ipv6/mcast.c:1855 mld_send_cr net/ipv6/mcast.c:2154 [inline] mld_ifc_work+0x83e/0xd60 net/ipv6/mcast.c:2693
--- net/ipv6/ip6_gre.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/ipv6/ip6_gre.c +8 -1
@@ -1383,9 +1383,16 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev, {struct ip6_tnl *t =netdev_priv (dev);struct ipv6hdr *ipv6h; +int needed;__be16 *p; - ipv6h =skb_push (skb, t->hlen +sizeof (*ipv6h)); + needed = t->hlen +sizeof (*ipv6h); +if (skb_headroom (skb) < needed && +pskb_expand_head (skb,HH_DATA_ALIGN (needed -skb_headroom (skb)), +0 ,GFP_ATOMIC )) +return -needed; + + ipv6h =skb_push (skb, needed);ip6_flow_hdr (ipv6h,0 ,ip6_make_flowlabel (dev_net (dev), skb, t->fl.u.ip6.flowlabel, true, &t->fl.u.ip6));
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 346/554 platform/x86: msi-laptop: add missing sysfs_remove_group()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit 1461209cf813b6ee6d40f29b96b544587df6d2b1 ]
A sysfs group is created in msi_init() when old_ec_model is enabled, but never removed. Remove the msipf_old_attribute_group in that case.
--- drivers/platform/x86/msi-laptop.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/x86/msi-laptop.c +3 -0
@@ -1146,6 +1146,9 @@ static void __exit msi_cleanup(void)sysfs_remove_group (&msipf_device->dev.kobj, &msipf_attribute_group);if (!quirks->old_ec_model && threeg_exists)device_remove_file (&msipf_device->dev, &dev_attr_threeg); +if (quirks->old_ec_model) +sysfs_remove_group (&msipf_device->dev.kobj, + &msipf_old_attribute_group);platform_device_unregister (msipf_device);platform_driver_unregister (&msipf_driver);backlight_device_unregister (msibl_device);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 347/554 platform/x86: ibm_rtl: fix EBDA signature search pointer arithmetic
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 15dd100349b8526cbdf2de0ce3e72e700eb6c208 ]
The ibm_rtl_init() function searches for the signature but has a pointer arithmetic error. The loop counter suggests searching at 4-byte intervals but the implementation only advances by 1 byte per iteration.
Fix by properly advancing the pointer by sizeof(unsigned int) bytes each iteration.
--- drivers/platform/x86/ibm_rtl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/ibm_rtl.c +1 -1
@@ -262,7 +262,7 @@ static int __init ibm_rtl_init(void) {/* search for the _RTL_ signature at the start of the table */ for (i =0 ; i < ebda_size/sizeof (unsigned int ); i++) {struct ibm_rtl_table __iomem * tmp; - tmp = (struct ibm_rtl_table __iomem *) (ebda_map+i); + tmp = (struct ibm_rtl_table __iomem *) (ebda_map + i*sizeof (unsigned int ));if ((readq (&tmp->signature) &RTL_MASK ) ==RTL_SIGNATURE ) {phys_addr_t addr;unsigned int plen;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 348/554 team: fix check for port enabled in team_queue_override_port_prio_changed()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Pirko <[email protected]>
[ Upstream commit 932ac51d9953eaf77a1252f79b656d4ca86163c6 ]
There has been a syzkaller bug reported recently with the following trace:
list_del corruption, ffff888058bea080->prev is LIST_POISON2 (dead000000000122)
------------[ cut here ]------------ kernel BUG at lib/list_debug.c:59! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 3 UID: 0 PID: 21246 Comm: syz.0.2928 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:__list_del_entry_valid_or_report+0x13e/0x200 lib/list_debug.c:59 Code: 48 c7 c7 e0 71 f0 8b e8 30 08 ef fc 90 0f 0b 48 89 ef e8 a5 02 55 fd 48 89 ea 48 89 de 48 c7 c7 40 72 f0 8b e8 13 08 ef fc 90 <0f> 0b 48 89 ef e8 88 02 55 fd 48 89 ea 48 b8 00 00 00 00 00 fc ff RSP: 0018:ffffc9000d49f370 EFLAGS: 00010286 RAX: 000000000000004e RBX: ffff888058bea080 RCX: ffffc9002817d000 RDX: 0000000000000000 RSI: ffffffff819becc6 RDI: 0000000000000005 RBP: dead000000000122 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000080000000 R11: 0000000000000001 R12: ffff888039e9c230 R13: ffff888058bea088 R14: ffff888058bea080 R15: ffff888055461480 FS: 00007fbbcfe6f6c0(0000) GS:ffff8880d6d0a000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000110c3afcb0 CR3: 00000000382c7000 CR4: 0000000000352ef0 Call Trace: <TASK> __list_del_entry_valid include/linux/list.h:132 [inline] __list_del_entry include/linux/list.h:223 [inline] list_del_rcu include/linux/rculist.h:178 [inline] __team_queue_override_port_del drivers/net/team/team_core.c:826 [inline] __team_queue_override_port_del drivers/net/team/team_core.c:821 [inline] team_queue_override_port_prio_changed drivers/net/team/team_core.c:883 [inline] team_priority_option_set+0x171/0x2f0 drivers/net/team/team_core.c:1534 team_option_set drivers/net/team/team_core.c:376 [inline] team_nl_options_set_doit+0x8ae/0xe60 drivers/net/team/team_core.c:2653 genl_family_rcv_msg_doit+0x209/0x2f0 net/netlink/genetlink.c:1115 genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] genl_rcv_msg+0x55c/0x800 net/netlink/genetlink.c:1210 netlink_rcv_skb+0x158/0x420 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+0x5aa/0x870 net/netlink/af_netlink.c:1346 netlink_sendmsg+0x8c8/0xdd0 net/netlink/af_netlink.c:1896 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg net/socket.c:742 [inline] ____sys_sendmsg+0xa98/0xc70 net/socket.c:2630 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2684 __sys_sendmsg+0x16d/0x220 net/socket.c:2716 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
The problem is in this flow:
1) Port is enabled, queue_id != 0, in qom_list
2) Port gets disabled
-> team_port_disable()
-> team_queue_override_port_del()
-> del (removed from list)
3) Port is disabled, queue_id != 0, not in any list
4) Priority changes
-> team_queue_override_port_prio_changed()
-> checks: port disabled && queue_id != 0
-> calls del - hits the BUG as it is removed alreadyTo fix this, change the check in team_queue_override_port_prio_changed() so it returns early if port is not enabled.
--- drivers/net/team/team.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/team/team.c +1 -1
@@ -873,7 +873,7 @@ static void __team_queue_override_enabled_check(struct team *team)static void team_queue_override_port_prio_changed (struct team *team,struct team_port *port) { -if (!port->queue_id ||team_port_enabled (port)) +if (!port->queue_id || !team_port_enabled (port))return ;__team_queue_override_port_del (team, port);__team_queue_override_port_add (team, port);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 349/554 net: usb: rtl8150: fix memory leak on usb_submit_urb() failure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepakkumar Karn <[email protected]>
[ Upstream commit 12cab1191d9890097171156d06bfa8d31f1e39c8 ]
In async_set_registers(), when usb_submit_urb() fails, the allocated
async_req structure and URB are not freed, causing a memory leak.
The completion callback async_set_reg_cb() is responsible for freeing these allocations, but it is only called after the URB is successfully submitted and completes (successfully or with error). If submission fails, the callback never runs and the memory is leaked.
Fix this by freeing both the URB and the request structure in the error path when usb_submit_urb() fails.
--- drivers/net/usb/rtl8150.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/usb/rtl8150.c +2 -0
@@ -211,6 +211,8 @@ static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg)if (res == -ENODEV )netif_device_detach (dev->netdev);dev_err (&dev->udev->dev,"%s failed with %d\n" , __func__, res); +kfree (req); +usb_free_urb (async_urb); }return res; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 350/554 smc91x: fix broken irq-context in PREEMPT_RT
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yeoreum Yun <[email protected]>
[ Upstream commit 6402078bd9d1ed46e79465e1faaa42e3458f8a33 ]
When smc91x.c is built with PREEMPT_RT, the following splat occurs in FVP_RevC:
[ 13.055000] smc91x LNRO0003:00 eth0: link up, 10Mbps, half-duplex, lpa 0x0000
[ 13.062137] BUG: workqueue leaked atomic, lock or RCU: kworker/2:1[106]
[ 13.062137] preempt=0x00000000 lock=0->0 RCU=0->1 workfn=mld_ifc_work
[ 13.062266] C
** replaying previous printk message **
[ 13.062266] CPU: 2 UID: 0 PID: 106 Comm: kworker/2:1 Not tainted 6.18.0-dirty #179 PREEMPT_{RT,(full)}
[ 13.062353] Hardware name: , BIOS
[ 13.062382] Workqueue: mld mld_ifc_work
[ 13.062469] Call trace:
[ 13.062494] show_stack+0x24/0x40 (C)
[ 13.062602] __dump_stack+0x28/0x48
[ 13.062710] dump_stack_lvl+0x7c/0xb0
[ 13.062818] dump_stack+0x18/0x34
[ 13.062926] process_scheduled_works+0x294/0x450
[ 13.063043] worker_thread+0x260/0x3d8
[ 13.063124] kthread+0x1c4/0x228
[ 13.063235] ret_from_fork+0x10/0x20This happens because smc_special_trylock() disables IRQs even on PREEMPT_RT,
but smc_special_unlock() does not restore IRQs on PREEMPT_RT.
The reason is that smc_special_unlock() calls spin_unlock_irqrestore(),
and rcu_read_unlock_bh() in __dev_queue_xmit() cannot invokercu_read_unlock() through __local_bh_enable_ip() when current->softirq_disable_cnt becomes zero.
To address this issue, replace smc_special_trylock() with spin_trylock_irqsave().
--- drivers/net/ethernet/smsc/smc91x.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
drivers/net/ethernet/smsc/smc91x.c +1 -9
@@ -515,15 +515,7 @@ static inline void smc_rcv(struct net_device *dev)* any other concurrent access and C would always interrupt B. But life * isn't that easy in a SMP world... */ -#define smc_special_trylock (lock, flags) \ -({ \ - int __ret; \ - local_irq_save(flags); \ - __ret = spin_trylock(lock); \ - if (!__ret) \ - local_irq_restore(flags); \ - __ret; \ -}) +#define smc_special_trylock (lock, flags) spin_trylock_irqsave(lock, flags)#define smc_special_lock (lock, flags) spin_lock_irqsave(lock, flags)#define smc_special_unlock (lock, flags) spin_unlock_irqrestore(lock, flags)#else
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 351/554 genalloc.h: fix htmldocs warning
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Morton <[email protected]>
[ Upstream commit 5393802c94e0ab1295c04c94c57bcb00222d4674 ]
WARNING: include/linux/genalloc.h:52 function parameter 'start_addr' not described in 'genpool_algo_t'
--- include/linux/genalloc.h | 1 + 1 file changed, 1 insertion(+)
include/linux/genalloc.h +1 -0
@@ -44,6 +44,7 @@ struct gen_pool;* @nr: The number of zeroed bits we're looking for * @data: optional additional data used by the callback * @pool: the pool being allocated from +* @start_addr: start address of memory chunk */ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 352/554 firewire: nosy: Fix dma_free_coherent() size
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit c48c0fd0e19684b6ecdb4108a429e3a4e73f5e21 ]
It looks like the buffer allocated and mapped in add_card() is done with size RCV_BUFFER_SIZE which is 16 KB and 4KB.
--- drivers/firewire/nosy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/firewire/nosy.c +5 -5
@@ -36,6 +36,8 @@static char driver_name[] =KBUILD_MODNAME ; +#define RCV_BUFFER_SIZE (16 * 1024) +/* this is the physical layout of a PCL, its size is 128 bytes */ struct pcl {__le32 next;
@@ -517,16 +519,14 @@ remove_card(struct pci_dev *dev) lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus);dma_free_coherent (&lynx->pci_device->dev,sizeof (struct pcl ), lynx->rcv_pcl, lynx->rcv_pcl_bus); -dma_free_coherent (&lynx->pci_device->dev,PAGE_SIZE , lynx->rcv_buffer, - lynx->rcv_buffer_bus); +dma_free_coherent (&lynx->pci_device->dev,RCV_BUFFER_SIZE , + lynx->rcv_buffer, lynx->rcv_buffer_bus);iounmap (lynx->registers);pci_disable_device (dev);lynx_put (lynx); } -#define RCV_BUFFER_SIZE (16 * 1024) -static int add_card (struct pci_dev *dev,const struct pci_device_id *unused) {
@@ -680,7 +680,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused)dma_free_coherent (&lynx->pci_device->dev,sizeof (struct pcl ), lynx->rcv_pcl, lynx->rcv_pcl_bus);if (lynx->rcv_buffer) -dma_free_coherent (&lynx->pci_device->dev,PAGE_SIZE , +dma_free_coherent (&lynx->pci_device->dev,RCV_BUFFER_SIZE , lynx->rcv_buffer, lynx->rcv_buffer_bus);iounmap (lynx->registers);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 353/554 net: dsa: b53: skip multicast entries for fdb_dump()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit d42bce414d1c5c0b536758466a1f63ac358e613c ]
port_fdb_dump() is supposed to only add fdb entries, but we iterate over the full ARL table, which also includes multicast entries.
So check if the entry is a multicast entry before passing it on to the callback().
Additionally, the port of those entries is a bitmask, not a port number, so any included entries would have even be for the wrong port.
--- drivers/net/dsa/b53/b53_common.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/dsa/b53/b53_common.c +3 -0
@@ -1832,6 +1832,9 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,if (!ent->is_valid)return 0 ; +if (is_multicast_ether_addr (ent->mac)) +return 0 ; +if (port != ent->port)return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 354/554 net: usb: asix: validate PHY address before use
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
[ Upstream commit a1e077a3f76eea0dc671ed6792e7d543946227e8 ]
The ASIX driver reads the PHY address from the USB device via asix_read_phy_addr(). A malicious or faulty device can return an invalid address (>= PHY_MAX_ADDR), which causes a warning in mdiobus_get_phy():
addr 207 out of range
WARNING: drivers/net/phy/mdio_bus.c:76
Validate the PHY address in asix_read_phy_addr() and remove the now-redundant check in ax88172a.c.
--- drivers/net/usb/asix_common.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/usb/asix_common.c +5 -0
@@ -333,6 +333,11 @@ int asix_read_phy_addr(struct usbnet *dev, bool internal) offset = (internal ?1 :0 ); ret = buf[offset]; +if (ret >=PHY_MAX_ADDR ) { +netdev_err (dev->net,"invalid PHY address: %d\n" , ret); +return -ENODEV ; + } +netdev_dbg (dev->net,"%s PHY address 0x%x\n" , internal ?"internal" :"external" , ret);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 355/554 net: bridge: Describe @tunnel_hash member in net_bridge_vlan_group struct
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bagas Sanjaya <[email protected]>
[ Upstream commit f79f9b7ace1713e4b83888c385f5f55519dfb687 ]
Sphinx reports kernel-doc warning:
WARNING: ./net/bridge/br_private.h:267 struct member 'tunnel_hash' not described in 'net_bridge_vlan_group'
Fix it by describing @tunnel_hash member.
--- net/bridge/br_private.h | 1 + 1 file changed, 1 insertion(+)
net/bridge/br_private.h +1 -0
@@ -221,6 +221,7 @@ struct net_bridge_vlan {* struct net_bridge_vlan_group * * @vlan_hash: VLAN entry rhashtable +* @tunnel_hash: Hash table to map from tunnel key ID (e.g. VXLAN VNI) to VLAN * @vlan_list: sorted VLAN entry list * @num_vlans: number of total VLAN entries * @pvid: PVID VLAN id
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 356/554 octeontx2-pf: fix "UBSAN: shift-out-of-bounds error"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anshumali Gaur <[email protected]>
[ Upstream commit 85f4b0c650d9f9db10bda8d3acfa1af83bf78cf7 ]
This patch ensures that the RX ring size (rx_pending) is not set below the permitted length. This avoids UBSAN shift-out-of-bounds errors when users passes small or zero ring sizes via ethtool -G.
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +8 -0
@@ -391,6 +391,14 @@ static int otx2_set_ringparam(struct net_device *netdev,*/ if (rx_count < pfvf->hw.rq_skid) rx_count = pfvf->hw.rq_skid; + +if (ring->rx_pending <16 ) { +netdev_err (netdev, +"rx ring size %u invalid, min is 16\n" , + ring->rx_pending); +return -EINVAL ; + } + rx_count =Q_COUNT (Q_SIZE (rx_count,3 ));/* Due pipelining impact minimum 2000 unused SQ CQE's
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 357/554 ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Rosenberg <[email protected]>
[ Upstream commit 58fc7342b529803d3c221101102fe913df7adb83 ]
There exists a kernel oops caused by a BUG_ON(nhead < 0) at net/core/skbuff.c:2232 in pskb_expand_head().
This bug is triggered as part of the calipso_skbuff_setattr() routine when skb_cow() is passed headroom > INT_MAX (i.e. (int)(skb_headroom(skb) + len_delta) < 0).
The root cause of the bug is due to an implicit integer cast in __skb_cow(). The check (headroom > skb_headroom(skb)) is meant to ensure that delta = headroom - skb_headroom(skb) is never negative, otherwise we will trigger a BUG_ON in pskb_expand_head(). However, if headroom > INT_MAX and delta <= -NET_SKB_PAD, the check passes, delta becomes negative, and pskb_expand_head() is passed a negative value for nhead.
Fix the trigger condition in calipso_skbuff_setattr(). Avoid passing "negative" headroom sizes to skb_cow() within calipso_skbuff_setattr() by only using skb_cow() to grow headroom.
PoC:
Using `netlabelctl` tool:
netlabelctl map del default
netlabelctl calipso add pass doi:7
netlabelctl map add default address:0::1/128 protocol:calipso,7
Then run the following PoC:
int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
// setup msghdr
int cmsg_size = 2;
int cmsg_len = 0x60;
struct msghdr msg;
struct sockaddr_in6 dest_addr;
struct cmsghdr * cmsg = (struct cmsghdr *) calloc(1,
sizeof(struct cmsghdr) + cmsg_len);
msg.msg_name = &dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_control = cmsg;
msg.msg_controllen = cmsg_len;
msg.msg_flags = 0;
// setup sockaddr
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(31337);
dest_addr.sin6_flowinfo = htonl(31337);
dest_addr.sin6_addr = in6addr_loopback;
dest_addr.sin6_scope_id = 31337;
// setup cmsghdr
cmsg->cmsg_len = cmsg_len;
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_HOPOPTS;
char * hop_hdr = (char *)cmsg + sizeof(struct cmsghdr);
hop_hdr[1] = 0x9; //set hop size - (0x9 + 1) * 8 = 80
sendmsg(fd, &msg, 0);--- net/ipv6/calipso.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/calipso.c +2 -1
@@ -1345,7 +1345,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */ pad = ((new_end &4 ) + (end &7 )) &7 ; len_delta = new_end - (int )end + pad; - ret_val =skb_cow (skb,skb_headroom (skb) + len_delta); + ret_val =skb_cow (skb, +skb_headroom (skb) + (len_delta >0 ? len_delta :0 ));if (ret_val <0 )return ret_val;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 358/554 ipv4: Fix reference count leak when using error routes with nexthop objects
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit ac782f4e3bfcde145b8a7f8af31d9422d94d172a ]
When a nexthop object is deleted, it is marked as dead and then fib_table_flush() is called to flush all the routes that are using the dead nexthop.
The current logic in fib_table_flush() is to only flush error routes (e.g., blackhole) when it is called as part of network namespace dismantle (i.e., with flush_all=true). Therefore, error routes are not flushed when their nexthop object is deleted:
# ip link add name dummy1 up type dummy # ip nexthop add id 1 dev dummy1 # ip route add 198.51.100.1/32 nhid 1 # ip route add blackhole 198.51.100.2/32 nhid 1 # ip nexthop del id 1 # ip route show blackhole 198.51.100.2 nhid 1 dev dummy1
As such, they keep holding a reference on the nexthop object which in turn holds a reference on the nexthop device, resulting in a reference count leak:
# ip link del dev dummy1 [ 70.516258] unregister_netdevice: waiting for dummy1 to become free. Usage count = 2
Fix by flushing error routes when their nexthop is marked as dead.
IPv6 does not suffer from this problem.
--- net/ipv4/fib_trie.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/ipv4/fib_trie.c +4 -3
@@ -2049,10 +2049,11 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all)continue ; } -/* Do not flush error routes if network namespace is -* not being dismantled +/* When not flushing the entire table, skip error +* routes that are not marked for deletion. */ -if (!flush_all && fib_props[fa->fa_type].error) { +if (!flush_all && fib_props[fa->fa_type].error && + !(fi->fib_flags &RTNH_F_DEAD )) { slen = fa->fa_slen;continue ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 359/554 net: rose: fix invalid array index in rose_kill_by_device()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pwnverse <[email protected]>
[ Upstream commit 6595beb40fb0ec47223d3f6058ee40354694c8e4 ]
rose_kill_by_device() collects sockets into a local array[] and then iterates over them to disconnect sockets bound to a device being brought down.
The loop mistakenly indexes array[cnt] instead of array[i]. For cnt < ARRAY_SIZE(array), this reads an uninitialized entry; for cnt == ARRAY_SIZE(array), it is an out-of-bounds read. Either case can lead to an invalid socket pointer dereference and also leaks references taken via sock_hold().
Fix the index to use i.
--- net/rose/af_rose.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/rose/af_rose.c +1 -1
@@ -204,7 +204,7 @@ static void rose_kill_by_device(struct net_device *dev)spin_unlock_bh (&rose_list_lock);for (i =0 ; i < cnt; i++) { - sk = array[cnt]; + sk = array[i]; rose =rose_sk (sk);lock_sock (sk);spin_lock_bh (&rose_list_lock);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 360/554 RDMA/irdma: avoid invalid read in irdma_net_event
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Schmidt <[email protected]>
[ Upstream commit 6f05611728e9d0ab024832a4f1abb74a5f5d0bb0 ]
irdma_net_event() should not dereference anything from "neigh" (alias "ptr") until it has checked that the event is NETEVENT_NEIGH_UPDATE. Other events come with different structures pointed to by "ptr" and they may be smaller than struct neighbour.
Move the read of neigh->dev under the NETEVENT_NEIGH_UPDATE case.
The bug is mostly harmless, but it triggers KASAN on debug kernels:
BUG: KASAN: stack-out-of-bounds in irdma_net_event+0x32e/0x3b0 [irdma] Read of size 8 at addr ffffc900075e07f0 by task kworker/27:2/542554 CPU: 27 PID: 542554 Comm: kworker/27:2 Kdump: loaded Not tainted 5.14.0-630.el9.x86_64+debug #1 Hardware name: [...] Workqueue: events rt6_probe_deferred Call Trace: <IRQ> dump_stack_lvl+0x60/0xb0 print_address_description.constprop.0+0x2c/0x3f0 print_report+0xb4/0x270 kasan_report+0x92/0xc0 irdma_net_event+0x32e/0x3b0 [irdma] notifier_call_chain+0x9e/0x180 atomic_notifier_call_chain+0x5c/0x110 rt6_do_redirect+0xb91/0x1080 tcp_v6_err+0xe9b/0x13e0 icmpv6_notify+0x2b2/0x630 ndisc_redirect_rcv+0x328/0x530 icmpv6_rcv+0xc16/0x1360 ip6_protocol_deliver_rcu+0xb84/0x12e0 ip6_input_finish+0x117/0x240 ip6_input+0xc4/0x370 ipv6_rcv+0x420/0x7d0 __netif_receive_skb_one_core+0x118/0x1b0 process_backlog+0xd1/0x5d0 __napi_poll.constprop.0+0xa3/0x440 net_rx_action+0x78a/0xba0 handle_softirqs+0x2d4/0x9c0 do_softirq+0xad/0xe0 </IRQ>
--- drivers/infiniband/hw/irdma/utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/irdma/utils.c +2 -1
@@ -251,7 +251,7 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event, void *ptr) {struct neighbour *neigh = ptr; -struct net_device *real_dev, *netdev = (struct net_device *)neigh->dev; +struct net_device *real_dev, *netdev;struct irdma_device *iwdev;struct ib_device *ibdev;__be32 *p;
@@ -260,6 +260,7 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event,switch (event) {case NETEVENT_NEIGH_UPDATE : + netdev = neigh->dev; real_dev =rdma_vlan_dev_real_dev (netdev);if (!real_dev) real_dev = netdev;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 361/554 RDMA/efa: Remove possible negative shift
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Margolin <[email protected]>
[ Upstream commit 85463eb6a46caf2f1e0e1a6d0731f2f3bab17780 ]
The page size used for device might in some cases be smaller than PAGE_SIZE what results in a negative shift when calculating the number of host pages in PAGE_SIZE for a debug log. Remove the debug line together with the calculation.
--- drivers/infiniband/hw/efa/efa_verbs.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/infiniband/hw/efa/efa_verbs.c +0 -4
@@ -1151,13 +1151,9 @@ static int umem_to_page_list(struct efa_dev *dev, u32 hp_cnt, u8 hp_shift) { -u32 pages_in_hp =BIT (hp_shift -PAGE_SHIFT );struct ib_block_iter biter;unsigned int hp_idx =0 ; -ibdev_dbg (&dev->ibdev,"hp_cnt[%u], pages_in_hp[%u]\n" , - hp_cnt, pages_in_hp); -rdma_umem_for_each_dma_block (umem, &biter,BIT (hp_shift)) page_list[hp_idx++] =rdma_block_iter_dma_address (&biter);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 362/554 RDMA/core: Fix logic error in ib_get_gids_from_rdma_hdr()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jang Ingyu <[email protected]>
[ Upstream commit 8aaa848eaddd9ef8680fc6aafbd3a0646da5df40 ]
Fix missing comparison operator for RDMA_NETWORK_ROCE_V1 in the conditional statement. The constant was used directly instead of being compared with net_type, causing the condition to always evaluate to true.
--- drivers/infiniband/core/verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/verbs.c +1 -1
@@ -740,7 +740,7 @@ int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr, (struct in6_addr *)dgid);return 0 ; }else if (net_type ==RDMA_NETWORK_IPV6 || - net_type ==RDMA_NETWORK_IB ||RDMA_NETWORK_ROCE_V1 ) { + net_type ==RDMA_NETWORK_IB || net_type ==RDMA_NETWORK_ROCE_V1 ) { *dgid = hdr->ibgrh.dgid; *sgid = hdr->ibgrh.sgid;return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 363/554 RDMA/bnxt_re: Fix incorrect BAR check in bnxt_qplib_map_creq_db()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit 145a417a39d7efbc881f52e829817376972b278c ]
RCFW_COMM_CONS_PCI_BAR_REGION is defined as BAR 2, so checking !creq_db->reg.bar_id is incorrect and always false.
pci_resource_start() returns the BAR base address, and a value of 0 indicates that the BAR is unassigned. Update the condition to test bar_base == 0 instead.
This ensures the driver detects and logs an error for an unassigned RCFW communication BAR.
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +1 -1
@@ -779,7 +779,7 @@ static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt) creq_db->reg.bar_id =RCFW_COMM_CONS_PCI_BAR_REGION ; creq_db->reg.bar_base =pci_resource_start (pdev, creq_db->reg.bar_id); -if (!creq_db->reg.bar_id) +if (!creq_db->reg.bar_base)dev_err (&pdev->dev,"QPLIB: CREQ BAR region %d resc start is 0!" , creq_db->reg.bar_id);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 364/554 RDMA/bnxt_re: Fix IB_SEND_IP_CSUM handling in post_send
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit f01765a2361323e78e3d91b1cb1d5527a83c5cf7 ]
The bnxt_re SEND path checks wr->send_flags to enable features such as IP checksum offload. However, send_flags is a bitmask and may contain multiple flags (e.g. IB_SEND_SIGNALED | IB_SEND_IP_CSUM), while the existing code uses a switch() statement that only matches when send_flags is exactly IB_SEND_IP_CSUM.
As a result, checksum offload is not enabled when additional SEND flags are present.
Replace the switch() with a bitmask test:
if (wr->send_flags & IB_SEND_IP_CSUM)
This ensures IP checksum offload is enabled correctly when multiple SEND flags are used.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +1 -6
@@ -2644,14 +2644,9 @@ int bnxt_re_post_send(struct ib_qp *ib_qp, const struct ib_send_wr *wr, wqe.rawqp1.lflags |=SQ_SEND_RAWETH_QP1_LFLAGS_ROCE_CRC ; } -switch (wr->send_flags) { -case IB_SEND_IP_CSUM : +if (wr->send_flags &IB_SEND_IP_CSUM ) wqe.rawqp1.lflags |=SQ_SEND_RAWETH_QP1_LFLAGS_IP_CHKSUM ; -break ; -default : -break ; - } fallthrough;case IB_WR_SEND_WITH_INV : rc =bnxt_re_build_send_wqe (qp, wr, &wqe);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 365/554 RDMA/bnxt_re: Fix to use correct page size for PDE table
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalesh AP <[email protected]>
[ Upstream commit 3d70e0fb0f289b0c778041c5bb04d099e1aa7c1c ]
In bnxt_qplib_alloc_init_hwq(), while allocating memory for PDE table driver incorrectly is using the "pg_size" value passed to the function. Fixed to use the right value 4K. Also, fixed the allocation size for PBL table.
--- drivers/infiniband/hw/bnxt_re/qplib_res.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_res.c +2 -2
@@ -242,7 +242,7 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,if (npbl %BIT (MAX_PDL_LVL_SHIFT )) npde++;/* Alloc PDE pages */ - sginfo.pgsize = npde * pg_size; + sginfo.pgsize = npde *ROCE_PG_SIZE_4K ; sginfo.npages =1 ; rc =__alloc_pbl (res, &hwq->pbl[PBL_LVL_0 ], &sginfo);if (rc)
@@ -250,7 +250,7 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,/* Alloc PBL pages */ sginfo.npages = npbl; - sginfo.pgsize =PAGE_SIZE ; + sginfo.pgsize =ROCE_PG_SIZE_4K ; rc =__alloc_pbl (res, &hwq->pbl[PBL_LVL_1 ], &sginfo);if (rc) goto fail;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 366/554 RDMA/rtrs: Fix clt_path::max_pages_per_mr calculation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Honggang LI <[email protected]>
[ Upstream commit 43bd09d5b750f700499ae8ec45fd41a4c48673e6 ]
If device max_mr_size bits in the range [mr_page_shift+31:mr_page_shift] are zero, the min3 function will set clt_path::max_pages_per_mr to zero.
alloc_path_reqs will pass zero, which is invalid, as the third parameter to ib_alloc_mr.
--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/ulp/rtrs/rtrs-clt.c +1 -0
@@ -1469,6 +1469,7 @@ static void query_fast_reg_mode(struct rtrs_clt_path *clt_path) mr_page_shift =max (12 ,ffs (ib_dev->attrs.page_size_cap) -1 ); max_pages_per_mr = ib_dev->attrs.max_mr_size;do_div (max_pages_per_mr, (1ull << mr_page_shift)); + max_pages_per_mr =min_not_zero ((u32 )max_pages_per_mr,U32_MAX ); clt_path->max_pages_per_mr =min3 (clt_path->max_pages_per_mr, (u32 )max_pages_per_mr, ib_dev->attrs.max_fast_reg_page_list_len);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 367/554 RDMA/bnxt_re: fix dma_free_coherent() pointer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit fcd431a9627f272b4c0bec445eba365fe2232a94 ]
The dma_alloc_coherent() allocates a dma-mapped buffer, pbl->pg_arr[i]. The dma_free_coherent() should pass the same buffer to dma_free_coherent() and not page-aligned.
--- drivers/infiniband/hw/bnxt_re/qplib_res.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_res.c +1 -3
@@ -70,9 +70,7 @@ static void __free_pbl(struct bnxt_qplib_res *res, struct bnxt_qplib_pbl *pbl,for (i =0 ; i < pbl->pg_count; i++) {if (pbl->pg_arr[i])dma_free_coherent (&pdev->dev, pbl->pg_size, - (void *)((unsigned long ) - pbl->pg_arr[i] & -PAGE_MASK ), + pbl->pg_arr[i], pbl->pg_map_arr[i]);else dev_warn(&pdev->dev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 368/554 selftests/ftrace: traceonoff_triggers: strip off names
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yipeng Zou <[email protected]>
[ Upstream commit b889b4fb4cbea3ca7eb9814075d6a51936394bd9 ]
The func_traceonoff_triggers.tc sometimes goes to fail on my board, Kunpeng-920.
[root@localhost]# ./ftracetest ./test.d/ftrace/func_traceonoff_triggers.tc -l fail.log === Ftrace unit tests === [1] ftrace - test for function traceon/off triggers [FAIL] [2] (instance) ftrace - test for function traceon/off triggers [UNSUPPORTED]
I look up the log, and it shows that the md5sum is different between csum1 and csum2.
++ cnt=611
++ sleep .1
+++ cnt_trace
+++ grep -v '^#' trace
+++ wc -l
++ cnt2=611
++ '[' 611 -ne 611 ']'
+++ cat tracing_on
++ on=0
++ '[' 0 '!=' 0 ']'
+++ md5sum trace
++ csum1='76896aa74362fff66a6a5f3cf8a8a500 trace'
++ sleep .1
+++ md5sum trace
++ csum2='ee8625a21c058818fc26e45c1ed3f6de trace'
++ '[' '76896aa74362fff66a6a5f3cf8a8a500 trace' '!=' 'ee8625a21c058818fc26e45c1ed3f6de trace' ']' ++ fail 'Tracing file is still changing'
++ echo Tracing file is still changing
Tracing file is still changing
++ exit_fail
++ exit 1
So I directly dump the trace file before md5sum, the diff shows that:
[root@localhost]# diff trace_1.log trace_2.log -y --suppress-common-lines dockerd-12285 [036] d.... 18385.510290: sched_stat | <...>-12285 [036] d.... 18385.510290: sched_stat dockerd-12285 [036] d.... 18385.510291: sched_swit | <...>-12285 [036] d.... 18385.510291: sched_swit <...>-740 [044] d.... 18385.602859: sched_stat | kworker/44:1-740 [044] d.... 18385.602859: sched_stat <...>-740 [044] d.... 18385.602860: sched_swit | kworker/44:1-740 [044] d.... 18385.602860: sched_swit
And we can see that <...> filed be filled with names.
We can strip off the names there to fix that.
After strip off the names:
kworker/u257:0-12 [019] d..2. 2528.758910: sched_stat | -12 [019] d..2. 2528.758910: sched_stat_runtime: comm=k kworker/u257:0-12 [019] d..2. 2528.758912: sched_swit | -12 [019] d..2. 2528.758912: sched_switch: prev_comm=kw <idle>-0 [000] d.s5. 2528.762318: sched_waki | -0 [000] d.s5. 2528.762318: sched_waking: comm=sshd pi <idle>-0 [037] dNh2. 2528.762326: sched_wake | -0 [037] dNh2. 2528.762326: sched_wakeup: comm=sshd pi <idle>-0 [037] d..2. 2528.762334: sched_swit | -0 [037] d..2. 2528.762334: sched_switch: prev_comm=sw
--- .../ftrace/test.d/ftrace/func_traceonoff_triggers.tc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc +3 -2
@@ -90,9 +90,10 @@ if [ $on != "0" ]; then fail "Tracing is not off" fi -csum1=`md5sum trace` +# Cannot rely on names being around as they are only cached, strip them +csum1=`cat trace | sed -e 's/^ *[^ ]*\(-[0-9][0-9]*\)/\1/' | md5sum` sleep $SLEEP_TIME -csum2=`md5sum trace` +csum2=`cat trace | sed -e 's/^ *[^ ]*\(-[0-9][0-9]*\)/\1/' | md5sum` if [ "$csum1" != "$csum2" ]; then fail "Tracing file is still changing"
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 369/554 ASoC: stm32: sai: fix device leak on probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit e26ff429eaf10c4ef1bc3dabd9bf27eb54b7e1f4 upstream.
Make sure to drop the reference taken when looking up the sync provider device and its driver data during DAI probe on probe failures and on unbind.
Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference.
--- sound/soc/stm/stm32_sai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/stm/stm32_sai.c +1 -1
@@ -127,6 +127,7 @@ static int stm32_sai_set_sync(struct stm } sai_provider =platform_get_drvdata (pdev); +put_device (&pdev->dev);if (!sai_provider) {dev_err (&sai_client->pdev->dev,"SAI sync provider data not found\n" );
@@ -143,7 +144,6 @@ static int stm32_sai_set_sync(struct stm ret =stm32_sai_sync_conf_provider (sai_provider, synco); error: -put_device (&pdev->dev);of_node_put (np_provider);return ret; }
Greg Kroah-Hartman
maintainerPATCH 370/554 ASoC: qcom: q6asm-dai: perform correct state check before closing
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
commit bfbb12dfa144d45575bcfe139a71360b3ce80237 upstream.
Do not stop a q6asm stream if its not started, this can result in unnecessary dsp command which will timeout anyway something like below:
q6asm-dai ab00000.remoteproc:glink-edge:apr:service@7:dais: CMD 10bcd timeout
Fix this by correctly checking the state.
--- sound/soc/qcom/qdsp6/q6asm-dai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/qcom/qdsp6/q6asm-dai.c +2 -1
@@ -237,13 +237,14 @@ static int q6asm_dai_prepare(struct snd_ prtd->pcm_count =snd_pcm_lib_period_bytes (substream); prtd->pcm_irq_pos =0 ;/* rate and channels are sent to audio driver */ -if (prtd->state) { +if (prtd->state ==Q6ASM_STREAM_RUNNING ) {/* clear the previous setup if any */ q6asm_cmd (prtd->audio_client, prtd->stream_id,CMD_CLOSE );q6asm_unmap_memory_regions (substream->stream, prtd->audio_client);q6routing_stream_close (soc_prtd->dai_link->id, substream->stream); + prtd->state =Q6ASM_STREAM_STOPPED ; } ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client,
Greg Kroah-Hartman
maintainerPATCH 371/554 ASoC: qcom: q6adm: the the copp device only during last instance
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
commit 74cc4f3ea4e99262ba0d619c6a4ee33e2cd47f65 upstream.
A matching Common object post processing instance is normally resused across multiple streams. However currently we close this on DSP even though there is a refcount on this copp object, this can result in below error.
q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: Found Matching Copp 0x0 qcom-q6adm aprsvc:service:4:8: cmd = 0x10325 return error = 0x2 q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: DSP returned error[2] q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: Found Matching Copp 0x0 qcom-q6adm aprsvc:service:4:8: cmd = 0x10325 return error = 0x2 q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: DSP returned error[2] qcom-q6adm aprsvc:service:4:8: cmd = 0x10327 return error = 0x2 qcom-q6adm aprsvc:service:4:8: DSP returned error[2]
qcom-q6adm aprsvc:service:4:8: Failed to close copp -22
qcom-q6adm aprsvc:service:4:8: cmd = 0x10327 return error = 0x2 qcom-q6adm aprsvc:service:4:8: DSP returned error[2]
qcom-q6adm aprsvc:service:4:8: Failed to close copp -22
Fix this by addressing moving the adm_close to copp_kref destructor callback.
--- sound/soc/qcom/qdsp6/q6adm.c | 146 ++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 75 deletions(-)
sound/soc/qcom/qdsp6/q6adm.c +71 -75
@@ -109,11 +109,75 @@ static struct q6copp *q6adm_find_copp(st } +static int q6adm_apr_send_copp_pkt (struct q6adm *adm,struct q6copp *copp, +struct apr_pkt *pkt,uint32_t rsp_opcode) +{ +struct device *dev = adm->dev; +uint32_t opcode = pkt->hdr.opcode; +int ret; + +mutex_lock (&adm->lock); + copp->result.opcode =0 ; + copp->result.status =0 ; + ret =apr_send_pkt (adm->apr, pkt); +if (ret <0 ) { +dev_err (dev,"Failed to send APR packet\n" ); + ret = -EINVAL ; + goto err; + } + +/* Wait for the callback with copp id */ +if (rsp_opcode) + ret =wait_event_timeout (copp->wait, + (copp->result.opcode == opcode) || + (copp->result.opcode == rsp_opcode), +msecs_to_jiffies (TIMEOUT_MS )); +else + ret =wait_event_timeout (copp->wait, + (copp->result.opcode == opcode), +msecs_to_jiffies (TIMEOUT_MS )); + +if (!ret) { +dev_err (dev,"ADM copp cmd timedout\n" ); + ret = -ETIMEDOUT ; + }else if (copp->result.status >0 ) { +dev_err (dev,"DSP returned error[%d]\n" , + copp->result.status); + ret = -EINVAL ; + } + +err: +mutex_unlock (&adm->lock); +return ret; +} + +static int q6adm_device_close (struct q6adm *adm,struct q6copp *copp, +int port_id,int copp_idx) +{ +struct apr_pkt close; + + close.hdr.hdr_field =APR_HDR_FIELD (APR_MSG_TYPE_SEQ_CMD , +APR_HDR_LEN (APR_HDR_SIZE ), +APR_PKT_VER ); + close.hdr.pkt_size =sizeof (close); + close.hdr.src_port = port_id; + close.hdr.dest_port = copp->id; + close.hdr.token = port_id <<16 | copp_idx; + close.hdr.opcode =ADM_CMD_DEVICE_CLOSE_V5 ; + +return q6adm_apr_send_copp_pkt (adm, copp, &close,0 ); +} +static void q6adm_free_copp (struct kref *ref) { struct q6copp *c = container_of(ref, struct q6copp, refcount);struct q6adm *adm = c->adm;unsigned long flags; +int ret; + + ret =q6adm_device_close (adm, c, c->afe_port, c->copp_idx); +if (ret <0 ) +dev_err (adm->dev,"Failed to close copp %d\n" , ret);spin_lock_irqsave (&adm->copps_list_lock, flags);clear_bit (c->copp_idx, &adm->copp_bitmap[c->afe_port]);
@@ -155,13 +219,13 @@ static int q6adm_callback(struct apr_devswitch (result->opcode) {case ADM_CMD_DEVICE_OPEN_V5 :case ADM_CMD_DEVICE_CLOSE_V5 : - copp =q6adm_find_copp (adm, port_idx, copp_idx); -if (!copp) -return 0 ; - - copp->result = *result; -wake_up (&copp->wait); -kref_put (&copp->refcount, q6adm_free_copp); +list_for_each_entry (copp, &adm->copps_list, node) { +if ((port_idx == copp->afe_port) && (copp_idx == copp->copp_idx)) { + copp->result = *result; +wake_up (&copp->wait); +break ; + } + }break ;case ADM_CMD_MATRIX_MAP_ROUTINGS_V5 : adm->result = *result;
@@ -234,65 +298,6 @@ static struct q6copp *q6adm_alloc_copp(sreturn c; } -static int q6adm_apr_send_copp_pkt (struct q6adm *adm,struct q6copp *copp, -struct apr_pkt *pkt,uint32_t rsp_opcode) -{ -struct device *dev = adm->dev; -uint32_t opcode = pkt->hdr.opcode; -int ret; - -mutex_lock (&adm->lock); - copp->result.opcode =0 ; - copp->result.status =0 ; - ret =apr_send_pkt (adm->apr, pkt); -if (ret <0 ) { -dev_err (dev,"Failed to send APR packet\n" ); - ret = -EINVAL ; - goto err; - } - -/* Wait for the callback with copp id */ -if (rsp_opcode) - ret =wait_event_timeout (copp->wait, - (copp->result.opcode == opcode) || - (copp->result.opcode == rsp_opcode), -msecs_to_jiffies (TIMEOUT_MS )); -else - ret =wait_event_timeout (copp->wait, - (copp->result.opcode == opcode), -msecs_to_jiffies (TIMEOUT_MS )); - -if (!ret) { -dev_err (dev,"ADM copp cmd timedout\n" ); - ret = -ETIMEDOUT ; - }else if (copp->result.status >0 ) { -dev_err (dev,"DSP returned error[%d]\n" , - copp->result.status); - ret = -EINVAL ; - } - -err: -mutex_unlock (&adm->lock); -return ret; -} - -static int q6adm_device_close (struct q6adm *adm,struct q6copp *copp, -int port_id,int copp_idx) -{ -struct apr_pkt close; - - close.hdr.hdr_field =APR_HDR_FIELD (APR_MSG_TYPE_SEQ_CMD , -APR_HDR_LEN (APR_HDR_SIZE ), -APR_PKT_VER ); - close.hdr.pkt_size =sizeof (close); - close.hdr.src_port = port_id; - close.hdr.dest_port = copp->id; - close.hdr.token = port_id <<16 | copp_idx; - close.hdr.opcode =ADM_CMD_DEVICE_CLOSE_V5 ; - -return q6adm_apr_send_copp_pkt (adm, copp, &close,0 ); -} - static struct q6copp *q6adm_find_matching_copp(struct q6adm *adm, int port_id, int topology, int mode, int rate,
@@ -567,15 +572,6 @@ EXPORT_SYMBOL_GPL(q6adm_matrix_map);*/ int q6adm_close (struct device *dev,struct q6copp *copp) { -struct q6adm *adm =dev_get_drvdata (dev->parent); -int ret =0 ; - - ret =q6adm_device_close (adm, copp, copp->afe_port, copp->copp_idx); -if (ret <0 ) { -dev_err (adm->dev,"Failed to close copp %d\n" , ret); -return ret; - } -kref_put (&copp->refcount, q6adm_free_copp);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 372/554 ASoC: qcom: qdsp6: q6asm-dai: set 10 ms period and buffer alignment.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
commit 81c53b52de21b8d5a3de55ebd06b6bf188bf7efd upstream.
DSP expects the periods to be aligned to fragment sizes, currently setting up to hw constriants on periods bytes is not going to work correctly as we can endup with periods sizes aligned to 32 bytes however not aligned to fragment size.
Update the constriants to use fragment size, and also set at step of 10ms for period size to accommodate DSP requirements of 10ms latency.
--- sound/soc/qcom/qdsp6/q6asm-dai.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/qcom/qdsp6/q6asm-dai.c +2 -2
@@ -413,13 +413,13 @@ static int q6asm_dai_open(struct snd_soc } ret =snd_pcm_hw_constraint_step (runtime,0 , -SNDRV_PCM_HW_PARAM_PERIOD_BYTES ,32 ); +SNDRV_PCM_HW_PARAM_PERIOD_SIZE ,480 );if (ret <0 ) {dev_err (dev,"constraint for period bytes step ret = %d\n" , ret); } ret =snd_pcm_hw_constraint_step (runtime,0 , -SNDRV_PCM_HW_PARAM_BUFFER_BYTES ,32 ); +SNDRV_PCM_HW_PARAM_BUFFER_SIZE ,480 );if (ret <0 ) {dev_err (dev,"constraint for buffer bytes step ret = %d\n" , ret);
Greg Kroah-Hartman
maintainerPATCH 373/554 iommu/apple-dart: fix device leak on of_xlate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit a6eaa872c52a181ae9a290fd4e40c9df91166d7a upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate().
--- drivers/iommu/apple-dart.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/apple-dart.c +2 -0
@@ -611,6 +611,8 @@ static int apple_dart_of_xlate(struct destruct apple_dart *cfg_dart;int i, sid; +put_device (&iommu_pdev->dev); +if (args->args_count !=1 )return -EINVAL ; sid = args->args[0 ];
Greg Kroah-Hartman
maintainerPATCH 374/554 iommu/exynos: fix device leak on of_xlate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 05913cc43cb122f9afecdbe775115c058b906e1b upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate().
Note that commit 1a26044954a6 ("iommu/exynos: add missing put_device() call in exynos_iommu_of_xlate()") fixed the leak in a couple of error paths, but the reference is still leaking on success.
--- drivers/iommu/exynos-iommu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/iommu/exynos-iommu.c +3 -6
@@ -1284,17 +1284,14 @@ static int exynos_iommu_of_xlate(structreturn -ENODEV ; data =platform_get_drvdata (sysmmu); -if (!data) { -put_device (&sysmmu->dev); +put_device (&sysmmu->dev); +if (!data)return -ENODEV ; - }if (!owner) { owner =kzalloc (sizeof (*owner),GFP_KERNEL ); -if (!owner) { -put_device (&sysmmu->dev); +if (!owner)return -ENOMEM ; - }INIT_LIST_HEAD (&owner->controllers);mutex_init (&owner->rpm_lock);
Greg Kroah-Hartman
maintainerPATCH 375/554 iommu/ipmmu-vmsa: fix device leak on of_xlate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 80aa518452c4aceb9459f9a8e3184db657d1b441 upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate().
--- drivers/iommu/ipmmu-vmsa.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/ipmmu-vmsa.c +2 -0
@@ -710,6 +710,8 @@ static int ipmmu_init_platform_device(stdev_iommu_priv_set (dev,platform_get_drvdata (ipmmu_pdev)); +put_device (&ipmmu_pdev->dev); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 376/554 iommu/mediatek-v1: fix device leak on probe_device()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit c77ad28bfee0df9cbc719eb5adc9864462cfb65b upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during probe_device().
--- drivers/iommu/mtk_iommu_v1.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/mtk_iommu_v1.c +2 -0
@@ -393,6 +393,8 @@ static int mtk_iommu_create_mapping(strureturn -EINVAL ;dev_iommu_priv_set (dev,platform_get_drvdata (m4updev)); + +put_device (&m4updev->dev); } ret =iommu_fwspec_add_ids (dev, args->args,1 );
Greg Kroah-Hartman
maintainerPATCH 377/554 iommu/mediatek: fix device leak on of_xlate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit b3f1ee18280363ef17f82b564fc379ceba9ec86f upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate().
--- drivers/iommu/mtk_iommu.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/mtk_iommu.c +2 -0
@@ -669,6 +669,8 @@ static int mtk_iommu_of_xlate(struct devreturn -EINVAL ;dev_iommu_priv_set (dev,platform_get_drvdata (m4updev)); + +put_device (&m4updev->dev); }return iommu_fwspec_add_ids (dev, args->args,1 );
Greg Kroah-Hartman
maintainerPATCH 378/554 iommu/omap: fix device leaks on probe_device()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit b5870691065e6bbe6ba0650c0412636c6a239c5a upstream.
Make sure to drop the references taken to the iommu platform devices when looking up their driver data during probe_device().
Note that the arch data device pointer added by commit 604629bcb505 ("iommu/omap: add support for late attachment of iommu devices") has never been used. Remove it to underline that the references are not needed.
--- drivers/iommu/omap-iommu.c | 2 +- drivers/iommu/omap-iommu.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-)
drivers/iommu/omap-iommu.c +1 -1
@@ -1682,6 +1682,7 @@ static struct iommu_device *omap_iommu_p } oiommu =platform_get_drvdata (pdev); +put_device (&pdev->dev);if (!oiommu) {of_node_put (np);kfree (arch_data);
@@ -1689,7 +1690,6 @@ static struct iommu_device *omap_iommu_p } tmp->iommu_dev = oiommu; - tmp->dev = &pdev->dev;of_node_put (np); }
drivers/iommu/omap-iommu.h +0 -2
@@ -88,7 +88,6 @@ struct omap_iommu {/** * struct omap_iommu_arch_data - omap iommu private data * @iommu_dev: handle of the OMAP iommu device -* @dev: handle of the iommu device * * This is an omap iommu private data object, which binds an iommu user * to its iommu device. This object should be placed at the iommu user's
@@ -97,7 +96,6 @@ struct omap_iommu {*/ struct omap_iommu_arch_data {struct omap_iommu *iommu_dev; -struct device *dev; };struct cr_regs {
Greg Kroah-Hartman
maintainerPATCH 379/554 iommu/sun50i: fix device leak on of_xlate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit f916109bf53864605d10bf6f4215afa023a80406 upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate().
--- drivers/iommu/sun50i-iommu.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iommu/sun50i-iommu.c +2 -0
@@ -756,6 +756,8 @@ static int sun50i_iommu_of_xlate(structdev_iommu_priv_set (dev,platform_get_drvdata (iommu_pdev)); +put_device (&iommu_pdev->dev); +return iommu_fwspec_add_ids (dev, &id,1 ); }
Greg Kroah-Hartman
maintainerPATCH 380/554 iommu/tegra: fix device leak on probe_device()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit c08934a61201db8f1d1c66fcc63fb2eb526b656d upstream.
Make sure to drop the reference taken to the iommu platform device when looking up its driver data during probe_device().
Note that commit 9826e393e4a8 ("iommu/tegra-smmu: Fix missing put_device() call in tegra_smmu_find") fixed the leak in an error path, but the reference is still leaking on success.
--- drivers/iommu/tegra-smmu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/iommu/tegra-smmu.c +2 -3
@@ -808,10 +808,9 @@ static struct tegra_smmu *tegra_smmu_finreturn NULL ; mc =platform_get_drvdata (pdev); -if (!mc) { -put_device (&pdev->dev); +put_device (&pdev->dev); +if (!mc)return NULL ; - }return mc->smmu; }
Greg Kroah-Hartman
maintainerPATCH 381/554 HID: logitech-dj: Remove duplicate error logging
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit ca389a55d8b2d86a817433bf82e0602b68c4d541 upstream.
logi_dj_recv_query_paired_devices() and logi_dj_recv_switch_to_dj_mode() both have 2 callers which all log an error if the function fails. Move the error logging to inside these 2 functions to remove the duplicated error logging in the callers.
While at it also move the logi_dj_recv_send_report() call error handling in logi_dj_recv_switch_to_dj_mode() to directly after the call. That call only fails if the report cannot be found and in that case it does nothing, so the msleep() is not necessary on failures.
--- drivers/hid/hid-logitech-dj.c | 56 +++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 33 deletions(-)
drivers/hid/hid-logitech-dj.c +23 -33
@@ -805,7 +805,6 @@ static void delayedwork_callback(structstruct dj_workitem workitem;unsigned long flags;int count; -int retval;dbg_hid ("%s\n" , __func__);
@@ -842,11 +841,7 @@ static void delayedwork_callback(structlogi_dj_recv_destroy_djhid_device (djrcv_dev, &workitem);break ;case WORKITEM_TYPE_UNKNOWN : - retval =logi_dj_recv_query_paired_devices (djrcv_dev); -if (retval) { -hid_err (djrcv_dev->hidpp,"%s: logi_dj_recv_query_paired_devices error: %d\n" , - __func__, retval); - } +logi_dj_recv_query_paired_devices (djrcv_dev);break ;case WORKITEM_TYPE_EMPTY :dbg_hid ("%s: device list is empty\n" , __func__);
@@ -1239,8 +1234,10 @@ static int logi_dj_recv_query_paired_dev djrcv_dev->last_query = jiffies; -if (djrcv_dev->type != recvr_type_dj) -return logi_dj_recv_query_hidpp_devices (djrcv_dev); +if (djrcv_dev->type != recvr_type_dj) { + retval =logi_dj_recv_query_hidpp_devices (djrcv_dev); + goto out; + } dj_report =kzalloc (sizeof (struct dj_report ),GFP_KERNEL );if (!dj_report)
@@ -1250,6 +1247,10 @@ static int logi_dj_recv_query_paired_dev dj_report->report_type =REPORT_TYPE_CMD_GET_PAIRED_DEVICES ; retval =logi_dj_recv_send_report (djrcv_dev, dj_report);kfree (dj_report); +out: +if (retval <0 ) +hid_err (djrcv_dev->hidpp,"%s error:%d\n" , __func__, retval); +return retval; }
@@ -1275,6 +1276,8 @@ static int logi_dj_recv_switch_to_dj_mod (u8 )timeout; retval =logi_dj_recv_send_report (djrcv_dev, dj_report); +if (retval) + goto out;/* * Ugly sleep to work around a USB 3.0 bug when the receiver is
@@ -1283,11 +1286,6 @@ static int logi_dj_recv_switch_to_dj_mod* 50 msec should gives enough time to the receiver to be ready. */ msleep (50 ); - -if (retval) { -kfree (dj_report); -return retval; - } }/*
@@ -1313,7 +1311,12 @@ static int logi_dj_recv_switch_to_dj_modHIDPP_REPORT_SHORT_LENGTH ,HID_OUTPUT_REPORT , HID_REQ_SET_REPORT); +out:kfree (dj_report); + +if (retval <0 ) +hid_err (hdev,"%s error:%d\n" , __func__, retval); +return retval; }
@@ -1835,11 +1838,8 @@ static int logi_dj_probe(struct hid_deviif (has_hidpp) { retval =logi_dj_recv_switch_to_dj_mode (djrcv_dev,0 ); -if (retval <0 ) { -hid_err (hdev,"%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n" , - __func__, retval); +if (retval <0 ) goto switch_to_dj_mode_fail; - } }/* This is enabling the polling urb on the IN endpoint */
@@ -1857,15 +1857,11 @@ static int logi_dj_probe(struct hid_devispin_lock_irqsave (&djrcv_dev->lock, flags); djrcv_dev->ready = true;spin_unlock_irqrestore (&djrcv_dev->lock, flags); - retval =logi_dj_recv_query_paired_devices (djrcv_dev); -if (retval <0 ) { -hid_err (hdev,"%s: logi_dj_recv_query_paired_devices error:%d\n" , - __func__, retval); -/* -* This can happen with a KVM, let the probe succeed, -* logi_dj_recv_queue_unknown_work will retry later. -*/ - } +/* +* This can fail with a KVM. Ignore errors to let the probe +* succeed, logi_dj_recv_queue_unknown_work will retry later. +*/ +logi_dj_recv_query_paired_devices (djrcv_dev); }return 0 ;
@@ -1882,18 +1878,12 @@ hid_hw_start_fail:#ifdef CONFIG_PM static int logi_dj_reset_resume (struct hid_device *hdev) { -int retval;struct dj_receiver_dev *djrcv_dev =hid_get_drvdata (hdev);if (!djrcv_dev || djrcv_dev->hidpp != hdev)return 0 ; - retval =logi_dj_recv_switch_to_dj_mode (djrcv_dev,0 ); -if (retval <0 ) { -hid_err (hdev,"%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n" , - __func__, retval); - } - +logi_dj_recv_switch_to_dj_mode (djrcv_dev,0 );return 0 ; }#endif
Greg Kroah-Hartman
maintainerPATCH 382/554 PCI/PM: Reinstate clearing state_saved in legacy and !PM codepaths
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
commit 894f475f88e06c0f352c829849560790dbdedbe5 upstream.
When a PCI device is suspended, it is normally the PCI core's job to save Config Space and put the device into a low power state. However drivers are allowed to assume these responsibilities. When they do, the PCI core can tell by looking at the state_saved flag in struct pci_dev: The flag is cleared before commencing the suspend sequence and it is set when pci_save_state() is called. If the PCI core finds the flag set late in the suspend sequence, it refrains from calling pci_save_state() itself.
But there are two corner cases where the PCI core neglects to clear the flag before commencing the suspend sequence:
* If a driver has legacy PCI PM callbacks, pci_legacy_suspend() neglects to clear the flag. The (stale) flag is subsequently queried by pci_legacy_suspend() itself and pci_legacy_suspend_late().
* If a device has no driver or its driver has no PCI PM callbacks, pci_pm_freeze() neglects to clear the flag. The (stale) flag is subsequently queried by pci_pm_freeze_noirq().
The flag may be set prior to suspend if the device went through error
recovery: Drivers commonly invoke pci_restore_state() + pci_save_state() to restore Config Space after reset.
The flag may also be set if drivers call pci_save_state() on probe to allow for recovery from subsequent errors.
The result is that pci_legacy_suspend_late() and pci_pm_freeze_noirq() don't call pci_save_state() and so the state that will be restored on resume is the one recorded on last error recovery or on probe, not the one that the device had on suspend. If the two states happen to be identical, there's no problem.
Reinstate clearing the flag in pci_legacy_suspend() and pci_pm_freeze(). The two functions used to do that until commit 4b77b0a2ba27 ("PCI: Clear saved_state after the state has been restored") deemed it unnecessary because it assumed that it's sufficient to clear the flag on resume in pci_restore_state(). The commit seemingly did not take into account that pci_save_state() and pci_restore_state() are not only used by power management code, but also for error recovery.
Devices without driver or whose driver has no PCI PM callbacks may be in runtime suspend when pci_pm_freeze() is called. Their state has already been saved, so don't clear the flag to skip a pointless pci_save_state() in pci_pm_freeze_noirq().
None of the drivers with legacy PCI PM callbacks seem to use runtime PM, so clear the flag unconditionally in their case.
--- drivers/pci/pci-driver.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/pci/pci-driver.c +4 -0
@@ -598,6 +598,8 @@ static int pci_legacy_suspend(struct devstruct pci_dev *pci_dev =to_pci_dev (dev);struct pci_driver *drv = pci_dev->driver; + pci_dev->state_saved = false; +if (drv && drv->suspend) {pci_power_t prev = pci_dev->current_state;int error;
@@ -999,6 +1001,8 @@ static int pci_pm_freeze(struct device *if (!pm) {pci_pm_default_suspend (pci_dev); +if (!pm_runtime_suspended (dev)) + pci_dev->state_saved = false;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 383/554 leds: leds-lp50xx: Allow LED 0 to be added to module bank
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Hitz <[email protected]>
commit 26fe74d598c32e7bc6f150edfc4aa43e1bee55db upstream.
led_banks contains LED module number(s) that should be grouped into the module bank. led_banks is 0-initialized.
By checking the led_banks entries for 0, un-set entries are detected. But a 0-entry also indicates that LED module 0 should be grouped into the module bank.
By only iterating over the available entries no check for unused entries is required and LED module 0 can be added to bank.
--- drivers/leds/leds-lp50xx.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/leds/leds-lp50xx.c +4 -6
@@ -347,17 +347,15 @@ out:return ret; } -static int lp50xx_set_banks (struct lp50xx *priv,u32 led_banks[]) +static int lp50xx_set_banks (struct lp50xx *priv,u32 led_banks[],int num_leds) {u8 led_config_lo, led_config_hi;u32 bank_enable_mask =0 ;int ret;int i; -for (i =0 ; i < priv->chip_info->max_modules; i++) { -if (led_banks[i]) - bank_enable_mask |= (1 << led_banks[i]); - } +for (i =0 ; i < num_leds; i++) + bank_enable_mask |= (1 << led_banks[i]); led_config_lo = bank_enable_mask; led_config_hi = bank_enable_mask >>8 ;
@@ -413,7 +411,7 @@ static int lp50xx_probe_leds(struct fwnoreturn ret; } - ret =lp50xx_set_banks (priv, led_banks); + ret =lp50xx_set_banks (priv, led_banks, num_leds);if (ret) {dev_err (priv->dev,"Cannot setup banked LEDs\n" );return ret;
Greg Kroah-Hartman
maintainerPATCH 384/554 leds: leds-lp50xx: LP5009 supports 3 modules for a total of 9 LEDs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Hitz <[email protected]>
commit 5246e3673eeeccb4f5bf4f42375dd495d465ac15 upstream.
LP5009 supports 9 LED outputs that are grouped into 3 modules.
--- drivers/leds/leds-lp50xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/leds/leds-lp50xx.c +1 -1
@@ -56,7 +56,7 @@/* There are 3 LED outputs per bank */ #define LP50XX_LEDS_PER_MODULE 3 -#define LP5009_MAX_LED_MODULES 2 +#define LP5009_MAX_LED_MODULES 3#define LP5012_MAX_LED_MODULES 4#define LP5018_MAX_LED_MODULES 6#define LP5024_MAX_LED_MODULES 8
Greg Kroah-Hartman
maintainerPATCH 385/554 mfd: altera-sysmgr: Fix device leak on sysmgr regmap lookup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit ccb7cd3218e48665f3c7e19eede0da5f069c323d upstream.
Make sure to drop the reference taken to the sysmgr platform device when retrieving its driver data.
Note that holding a reference to a device does not prevent its driver data from going away.
--- drivers/mfd/altera-sysmgr.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mfd/altera-sysmgr.c +2 -0
@@ -118,6 +118,8 @@ struct regmap *altr_sysmgr_regmap_lookup sysmgr =dev_get_drvdata (dev); +put_device (dev); +return sysmgr->regmap; }EXPORT_SYMBOL_GPL (altr_sysmgr_regmap_lookup_by_phandle);
Greg Kroah-Hartman
maintainerPATCH 386/554 mfd: max77620: Fix potential IRQ chip conflict when probing two devices
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 2bac49bad1f3553cc3b3bfb22cc194e9bd9e8427 upstream.
MAX77620 is most likely always a single device on the board, however nothing stops board designers to have two of them, thus same device driver could probe twice. Or user could manually try to probing second time.
Device driver is not ready for that case, because it allocates statically 'struct regmap_irq_chip' as non-const and stores during probe in 'irq_drv_data' member a pointer to per-probe state container ('struct max77620_chip'). devm_regmap_add_irq_chip() does not make a copy of 'struct regmap_irq_chip' but store the pointer.
Second probe - either successful or failure - would overwrite the 'irq_drv_data' from previous device probe, so interrupts would be executed in a wrong context.
--- drivers/mfd/max77620.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/mfd/max77620.c +11 -4
@@ -254,7 +254,7 @@ static int max77620_irq_global_unmask(voreturn ret; } -static struct regmap_irq_chip max77620_top_irq_chip = { +static const struct regmap_irq_chip max77620_top_irq_chip = { .name ="max77620-top" , .irqs = max77620_top_irqs, .num_irqs =ARRAY_SIZE (max77620_top_irqs),
@@ -499,6 +499,7 @@ static int max77620_probe(struct i2c_cli {const struct regmap_config *rmap_config;struct max77620_chip *chip; +struct regmap_irq_chip *chip_desc;const struct mfd_cell *mfd_cells;int n_mfd_cells;bool pm_off;
@@ -509,6 +510,14 @@ static int max77620_probe(struct i2c_clireturn -ENOMEM ;i2c_set_clientdata (client, chip); + + chip_desc =devm_kmemdup (&client->dev, &max77620_top_irq_chip, +sizeof (max77620_top_irq_chip), +GFP_KERNEL ); +if (!chip_desc) +return -ENOMEM ; + chip_desc->irq_drv_data = chip; + chip->dev = &client->dev; chip->chip_irq = client->irq; chip->chip_id = (enum max77620_chip_id )id->driver_data;
@@ -545,11 +554,9 @@ static int max77620_probe(struct i2c_cliif (ret <0 )return ret; - max77620_top_irq_chip.irq_drv_data = chip; ret =devm_regmap_add_irq_chip (chip->dev, chip->rmap, client->irq,IRQF_ONESHOT |IRQF_SHARED ,0 , - &max77620_top_irq_chip, - &chip->top_irq_data); + chip_desc, &chip->top_irq_data);if (ret <0 ) {dev_err (chip->dev,"Failed to add regmap irq: %d\n" , ret);return ret;
Greg Kroah-Hartman
maintainerPATCH 387/554 media: rc: st_rc: Fix reset control resource leak
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
commit 1240abf4b71f632f0117b056e22488e4d9808938 upstream.
The driver calls reset_control_get_optional_exclusive() but never calls reset_control_put() in error paths or in the remove function. This causes a resource leak when probe fails after successfully acquiring the reset control, or when the driver is unloaded.
Switch to devm_reset_control_get_optional_exclusive() to automatically manage the reset control resource.
--- drivers/media/rc/st_rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/rc/st_rc.c +1 -1
@@ -287,7 +287,7 @@ static int st_rc_probe(struct platform_delse rc_dev->rx_base = rc_dev->base; - rc_dev->rstc =reset_control_get_optional_exclusive (dev,NULL ); + rc_dev->rstc =devm_reset_control_get_optional_exclusive (dev,NULL );if (IS_ERR (rc_dev->rstc)) { ret =PTR_ERR (rc_dev->rstc); goto err;
Greg Kroah-Hartman
maintainerPATCH 388/554 parisc: entry.S: fix space adjustment on interruption for 64-bit userspace
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Schnelle <[email protected]>
commit 1aa4524c0c1b54842c4c0a370171d11b12d0709b upstream.
In wide mode, the IASQ contain the upper part of the GVA during interruption. This needs to be reversed before the space is used - otherwise it contains parts of IAOQ. See Page 2-13 "Processing Resources / Interruption Instruction Address Queues" in the Parisc 2.0 Architecture Manual page 2-13 for an explanation.
The IAOQ/IASQ space_adjust was skipped for other interruptions than itlb misses. However, the code in handle_interruption() checks whether iasq[0] contains a valid space. Due to the not masked out bits this match failed and the process was killed.
Also add space_adjust for IAOQ1/IASQ1 so ptregs contains sane values.
--- arch/parisc/kernel/entry.S | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/parisc/kernel/entry.S +8 -3
@@ -1072,8 +1072,6 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ STREG %r17, PT_IOR(%r29) #if defined(CONFIG_64BIT) - b,n intr_save2 - skip_save_ior: /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
@@ -1082,10 +1080,17 @@ skip_save_ior: bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 - /* adjust iasq/iaoq */ + /* adjust iasq0/iaoq0 */ space_adjust %r16,%r17,%r1 STREG %r16, PT_IASQ0(%r29) STREG %r17, PT_IAOQ0(%r29) + + LDREG PT_IASQ1(%r29), %r16 + LDREG PT_IAOQ1(%r29), %r17 + /* adjust iasq1/iaoq1 */ + space_adjust %r16,%r17,%r1 + STREG %r16, PT_IASQ1(%r29) + STREG %r17, PT_IAOQ1(%r29) #else skip_save_ior: #endif
Greg Kroah-Hartman
maintainerPATCH 389/554 parisc: entry: set W bit for !compat tasks in syscall_restore_rfi()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Schnelle <[email protected]>
commit 5fb1d3ce3e74a4530042795e1e065422295f1371 upstream.
When the kernel leaves to userspace via syscall_restore_rfi(), the W bit is not set in the new PSW. This doesn't cause any problems because there's no 64 bit userspace for parisc. Simple static binaries are usually loaded at addresses way below the 32 bit limit so the W bit doesn't matter.
Fix this by setting the W bit when TIF_32BIT is not set.
--- arch/parisc/kernel/asm-offsets.c | 2 ++ arch/parisc/kernel/entry.S | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-)
arch/parisc/kernel/asm-offsets.c +2 -0
@@ -260,6 +260,8 @@ int main(void)BLANK ();DEFINE (TIF_BLOCKSTEP_PA_BIT ,31 -TIF_BLOCKSTEP );DEFINE (TIF_SINGLESTEP_PA_BIT ,31 -TIF_SINGLESTEP ); +DEFINE (TIF_32BIT_PA_BIT ,31 -TIF_32BIT ); +BLANK ();DEFINE (ASM_PMD_SHIFT ,PMD_SHIFT );DEFINE (ASM_PGDIR_SHIFT ,PGDIR_SHIFT );
arch/parisc/kernel/entry.S +4 -1
@@ -1913,6 +1913,10 @@ syscall_restore_rfi: extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0 depi -1,7,1,%r20 /* T bit */ +#ifdef CONFIG_64BIT + extru,<> %r19,TIF_32BIT_PA_BIT,1,%r0 + depi -1,4,1,%r20 /* W bit */ +#endif STREG %r20,TASK_PT_PSW(%r1) /* Always store space registers, since sr3 can be changed (e.g. fork) */
@@ -1926,7 +1930,6 @@ syscall_restore_rfi: STREG %r25,TASK_PT_IASQ0(%r1) STREG %r25,TASK_PT_IASQ1(%r1) - /* XXX W bit??? */ /* Now if old D bit is clear, it means we didn't save all registers * on syscall entry, so do that now. This only happens on TRACEME * calls, or if someone attached to us while we were on a syscall.
Greg Kroah-Hartman
maintainerPATCH 390/554 media: adv7842: Avoid possible out-of-bounds array accesses in adv7842_cp_log_status()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Abramov <[email protected]>
commit 8163419e3e05d71dcfa8fb49c8fdf8d76908fe51 upstream.
It's possible for cp_read() and hdmi_read() to return -EIO. Those values are further used as indexes for accessing arrays.
Fix that by checking return values where it's needed.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/media/i2c/adv7842.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/media/i2c/adv7842.c +5 -2
@@ -2690,6 +2690,7 @@ static int adv7842_cp_log_status(struct/* CP block */ struct adv7842_state *state =to_state (sd);struct v4l2_dv_timings timings; +int temp;u8 reg_io_0x02 =io_read (sd,0x02 );u8 reg_io_0x21 =io_read (sd,0x21 );u8 reg_rep_0x77 =rep_read (sd,0x77 );
@@ -2812,8 +2813,9 @@ static int adv7842_cp_log_status(struct (((reg_io_0x02 >>2 ) &0x01 ) ^ (reg_io_0x02 &0x01 )) ?"(16-235)" :"(0-255)" , (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); + temp =cp_read (sd,0xf4 ) >>4 ;v4l2_info (sd,"Color space conversion: %s\n" , - csc_coeff_sel_rb[cp_read (sd,0xf4 ) >>4 ]); + temp <0 ?"" : csc_coeff_sel_rb[temp]);if (!is_digital_input (sd))return 0 ;
@@ -2843,8 +2845,9 @@ static int adv7842_cp_log_status(struct hdmi_read(sd, 0x5f));v4l2_info (sd,"AV Mute: %s\n" , (hdmi_read (sd,0x04 ) &0x40 ) ?"on" :"off" ); + temp =hdmi_read (sd,0x0b ) >>6 ;v4l2_info (sd,"Deep color mode: %s\n" , - deep_color_mode_txt[hdmi_read (sd,0x0b ) >>6 ]); + temp <0 ?"" : deep_color_mode_txt[temp]);adv7842_log_infoframes (sd);
Greg Kroah-Hartman
maintainerPATCH 391/554 dm-ebs: Mark full buffer dirty even on partial write
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uladzislau Rezki (Sony) <[email protected]>
commit 7fa3e7d114abc9cc71cc35d768e116641074ddb4 upstream.
When performing a read-modify-write(RMW) operation, any modification to a buffered block must cause the entire buffer to be marked dirty.
Marking only a subrange as dirty is incorrect because the underlying device block size(ubs) defines the minimum read/write granularity. A lower device can perform I/O only on regions which are fully aligned and sized to ubs.
This change ensures that write-back operations always occur in full ubs-sized chunks, matching the intended emulation semantics of the EBS target.
As for user space visible impact, submitting sub-ubs and misaligned I/O for devices which are tuned to ubs sizes only, will reject such requests, therefore it can lead to losing data. Example:
1) Create a 8K nvme device in qemu by adding
-device nvme,drive=drv0,serial=foo,logical_block_size=8192,physical_block_size=8192
2) Setup dm-ebs to emulate 512B to 8K mapping
urezki@pc638:~/bin$ cat dmsetup.sh
lower=/dev/nvme0n1
len=$(blockdev --getsz "$lower")
echo "0 $len ebs $lower 0 1 16" | dmsetup create nvme-8k urezki@pc638:~/bin$
offset 0, ebs=1 and ubs=16(in sectors).
3) Create an ext4 filesystem(default 4K block size)
urezki@pc638:~/bin$ sudo mkfs.ext4 -F /dev/dm-0
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: done
Creating filesystem with 2072576 4k blocks and 518144 inodes
Filesystem UUID: bd0b6ca6-0506-4e31-86da-8d22c9d50b63
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: mkfs.ext4: Input/output error while writing out and closing file system
urezki@pc638:~/bin$ dmesg
<snip>
[ 1618.875449] buffer_io_error: 1028 callbacks suppressed [ 1618.875456] Buffer I/O error on dev dm-0, logical block 0, lost async page write [ 1618.875527] Buffer I/O error on dev dm-0, logical block 1, lost async page write [ 1618.875602] Buffer I/O error on dev dm-0, logical block 2, lost async page write [ 1618.875620] Buffer I/O error on dev dm-0, logical block 3, lost async page write [ 1618.875639] Buffer I/O error on dev dm-0, logical block 4, lost async page write [ 1618.894316] Buffer I/O error on dev dm-0, logical block 5, lost async page write [ 1618.894358] Buffer I/O error on dev dm-0, logical block 6, lost async page write [ 1618.894380] Buffer I/O error on dev dm-0, logical block 7, lost async page write [ 1618.894405] Buffer I/O error on dev dm-0, logical block 8, lost async page write [ 1618.894427] Buffer I/O error on dev dm-0, logical block 9, lost async page write
<snip>
Many I/O errors because the lower 8K device rejects sub-ubs/misaligned requests.
with a patch:
urezki@pc638:~/bin$ sudo mkfs.ext4 -F /dev/dm-0
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: done
Creating filesystem with 2072576 4k blocks and 518144 inodes
Filesystem UUID: 9b54f44f-ef55-4bd4-9e40-c8b775a616ac
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
urezki@pc638:~/bin$ sudo mount /dev/dm-0 /mnt/ urezki@pc638:~/bin$ ls -al /mnt/ total 24 drwxr-xr-x 3 root root 4096 Oct 17 15:13 . drwxr-xr-x 19 root root 4096 Jul 10 19:42 .. drwx------ 2 root root 16384 Oct 17 15:13 lost+found urezki@pc638:~/bin$
After this change: mkfs completes; mount succeeds.
--- drivers/md/dm-ebs-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-ebs-target.c +1 -1
@@ -101,7 +101,7 @@ static int __ebs_rw_bvec(struct ebs_c *e }else {flush_dcache_page (bv->bv_page);memcpy (ba, pa, cur_len); -dm_bufio_mark_partial_buffer_dirty (b, buf_off, buf_off + cur_len); +dm_bufio_mark_buffer_dirty (b); }dm_bufio_release (b);
Greg Kroah-Hartman
maintainerPATCH 392/554 fbdev: gbefb: fix to use physical address instead of dma address
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rene Rebe <[email protected]>
commit e3f44742bbb10537fe53d83d20dea2a7c167674d upstream.
While debuggigng why X would not start on mips64 Sgi/O2 I found the phys adress being off. Turns out the gbefb passed the internal dma_addr as phys. May be broken pre git history. Fix by converting dma_to_phys.
--- drivers/video/fbdev/gbefb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/video/fbdev/gbefb.c +3 -2
@@ -12,6 +12,7 @@#include <linux/delay.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/dma-direct.h> #include <linux/errno.h> #include <linux/gfp.h> #include <linux/fb.h>
@@ -65,7 +66,7 @@ struct gbefb_par {static unsigned int gbe_mem_size =CONFIG_FB_GBE_MEM *1024 *1024 ;static void *gbe_mem;static dma_addr_t gbe_dma_addr; -static unsigned long gbe_mem_phys; +static phys_addr_t gbe_mem_phys; static struct { uint16_t *cpu;
@@ -1187,7 +1188,7 @@ static int gbefb_probe(struct platform_d goto out_release_mem_region; } - gbe_mem_phys = (unsigned long ) gbe_dma_addr; + gbe_mem_phys =dma_to_phys (&p_dev->dev, gbe_dma_addr); } par = info->par;
Greg Kroah-Hartman
maintainerPATCH 393/554 fbdev: pxafb: Fix multiple clamped values in pxafb_adjust_timing
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 0155e868cbc111846cc2809c1546ea53810a56ae upstream.
The variables were never clamped because the return value of clamp_val() was not used. Fix this by assigning the clamped values, and use clamp() instead of clamp_val().
--- drivers/video/fbdev/pxafb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/video/fbdev/pxafb.c +6 -6
@@ -418,12 +418,12 @@ static int pxafb_adjust_timing(struct px var->yres =max_t (int, var->yres,MIN_YRES );if (!(fbi->lccr0 &LCCR0_LCDT )) { -clamp_val (var->hsync_len,1 ,64 ); -clamp_val (var->vsync_len,1 ,64 ); -clamp_val (var->left_margin,1 ,255 ); -clamp_val (var->right_margin,1 ,255 ); -clamp_val (var->upper_margin,1 ,255 ); -clamp_val (var->lower_margin,1 ,255 ); + var->hsync_len =clamp (var->hsync_len,1 ,64 ); + var->vsync_len =clamp (var->vsync_len,1 ,64 ); + var->left_margin =clamp (var->left_margin,1 ,255 ); + var->right_margin =clamp (var->right_margin,1 ,255 ); + var->upper_margin =clamp (var->upper_margin,1 ,255 ); + var->lower_margin =clamp (var->lower_margin,1 ,255 ); }/* make sure each line is aligned on word boundary */
Greg Kroah-Hartman
maintainerPATCH 394/554 fbdev: tcx.c fix mem_map to correct smem_start offset
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: René Rebe <[email protected]>
commit 35fa2b4bf96415b88d7edaa5cf8af5185d9ce76e upstream.
403ae52ac047 ("sparc: fix drivers/video/tcx.c warning") changed the physbase initializing breaking the user-space mmap, e.g. for Xorg entirely.
Fix fbdev mmap table so the sbus mmap helper work correctly, and not try to map vastly (physbase) offset memory.
--- drivers/video/fbdev/tcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/tcx.c +1 -1
@@ -436,7 +436,7 @@ static int tcx_probe(struct platform_dev j = i;break ; } - par->mmap_map[i].poff = op->resource[j].start; + par->mmap_map[i].poff = op->resource[j].start - info->fix.smem_start; } info->flags =FBINFO_DEFAULT ;
Greg Kroah-Hartman
maintainerPATCH 395/554 media: cec: Fix debugfs leak on bus_register() failure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
commit c43bcd2b2aa3c2ca9d2433c3990ecbc2c47d10eb upstream.
In cec_devnode_init(), the debugfs directory created with debugfs_create_dir() is not removed if bus_register() fails. This leaves a stale "cec" entry in debugfs and prevents proper module reloading.
Fix this by removing the debugfs directory in the error path.
--- drivers/media/cec/core/cec-core.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/cec/core/cec-core.c +1 -0
@@ -433,6 +433,7 @@ static int __init cec_devnode_init(void) ret =bus_register (&cec_bus_type);if (ret <0 ) { +debugfs_remove_recursive (top_cec_dir);unregister_chrdev_region (cec_dev_t,CEC_NUM_DEVICES );pr_warn ("cec: bus_register failed\n" );return -EIO ;
Greg Kroah-Hartman
maintainerPATCH 396/554 media: msp3400: Avoid possible out-of-bounds array accesses in msp3400c_thread()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Abramov <[email protected]>
commit d2bceb2e20e783d57e739c71e4e50b4b9f4a3953 upstream.
It's possible for max1 to remain -1 if msp_read() always fail. This variable is further used as index for accessing arrays.
Fix that by checking max1 prior to array accesses.
It seems that restart is the preferable action in case of out-of-bounds value.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/media/i2c/msp3400-kthreads.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/i2c/msp3400-kthreads.c +2 -0
@@ -596,6 +596,8 @@ restart: "carrier2 val: %5d / %s\n", val, cd[i].name); } +if (max1 <0 || max1 >3 ) + goto restart;/* program the msp3400 according to the results */ state->main = msp3400c_carrier_detect_main[max1].cdo;switch (max1) {
Greg Kroah-Hartman
maintainerPATCH 397/554 media: TDA1997x: Remove redundant cancel_delayed_work in probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <[email protected]>
commit 29de195ca39fc2ac0af6fd45522994df9f431f80 upstream.
The delayed_work delayed_work_enable_hpd is initialized with INIT_DELAYED_WORK(), but it is never scheduled in tda1997x_probe().
Calling cancel_delayed_work() on a work that has never been scheduled is redundant and unnecessary, as there is no pending work to cancel.
Remove the redundant cancel_delayed_work() from error handling path in tda1997x_probe() to avoid potential confusion.
--- drivers/media/i2c/tda1997x.c | 1 - 1 file changed, 1 deletion(-)
drivers/media/i2c/tda1997x.c +0 -1
@@ -2780,7 +2780,6 @@ err_free_media: err_free_handler:v4l2_ctrl_handler_free (&state->hdl); err_free_mutex: -cancel_delayed_work (&state->delayed_work_enable_hpd);mutex_destroy (&state->page_lock);mutex_destroy (&state->lock); err_free_state:
Greg Kroah-Hartman
maintainerPATCH 398/554 media: i2c: ADV7604: Remove redundant cancel_delayed_work in probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <[email protected]>
commit 8f34f24355a607b98ecd9924837aab13c676eeca upstream.
The delayed_work delayed_work_enable_hotplug is initialized with INIT_DELAYED_WORK() in adv76xx_probe(), but it is never scheduled anywhere in the probe function.
Calling cancel_delayed_work() on a work that has never been scheduled is redundant and unnecessary, as there is no pending work to cancel.
Remove the redundant cancel_delayed_work() from error handling path and adjust the goto label accordingly to simplify the code and avoid potential confusion.
--- drivers/media/i2c/adv7604.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/media/i2c/adv7604.c +1 -3
@@ -3615,7 +3615,7 @@ static int adv76xx_probe(struct i2c_clie err =media_entity_pads_init (&sd->entity, state->source_pad +1 , state->pads);if (err) - goto err_work_queues; + goto err_i2c;/* Configure regmaps */ err =configure_regmaps (state);
@@ -3656,8 +3656,6 @@ static int adv76xx_probe(struct i2c_clie err_entity:media_entity_cleanup (&sd->entity); -err_work_queues: -cancel_delayed_work (&state->delayed_work_enable_hotplug); err_i2c:adv76xx_unregister_clients (state); err_hdl:
Greg Kroah-Hartman
maintainerPATCH 399/554 media: i2c: adv7842: Remove redundant cancel_delayed_work in probe
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <[email protected]>
commit e66a5cc606c58e72f18f9cdd868a3672e918f9f8 upstream.
The delayed_work delayed_work_enable_hotplug is initialized with INIT_DELAYED_WORK() in adv7842_probe(), but it is never scheduled anywhere in the probe function.
Calling cancel_delayed_work() on a work that has never been scheduled is redundant and unnecessary, as there is no pending work to cancel.
Remove the redundant cancel_delayed_work() from error handling path and adjust the goto label accordingly to simplify the code and avoid potential confusion.
--- drivers/media/i2c/adv7842.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/media/i2c/adv7842.c +1 -3
@@ -3575,7 +3575,7 @@ static int adv7842_probe(struct i2c_clie err =media_entity_pads_init (&sd->entity,ADV7842_PAD_SOURCE +1 , state->pads);if (err) - goto err_work_queues; + goto err_i2c; err =adv7842_core_init (sd);if (err)
@@ -3596,8 +3596,6 @@ static int adv7842_probe(struct i2c_clie err_entity:media_entity_cleanup (&sd->entity); -err_work_queues: -cancel_delayed_work (&state->delayed_work_enable_hotplug); err_i2c:adv7842_unregister_clients (sd); err_hdl:
Greg Kroah-Hartman
maintainerPATCH 400/554 idr: fix idr_alloc() returning an ID out of range
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <[email protected]>
commit c6e8e595a0798ad67da0f7bebaf69c31ef70dfff upstream.
If you use an IDR with a non-zero base, and specify a range that lies entirely below the base, 'max - base' becomes very large and idr_get_free() can return an ID that lies outside of the requested range.
--- lib/idr.c | 2 ++ tools/testing/radix-tree/idr-test.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+)
lib/idr.c +2 -0
@@ -40,6 +40,8 @@ int idr_alloc_u32(struct idr *idr, voidif (WARN_ON_ONCE (!(idr->idr_rt.xa_flags &ROOT_IS_IDR ))) idr->idr_rt.xa_flags |=IDR_RT_MARKER ; +if (max < base) +return -ENOSPC ; id = (id < base) ?0 : id - base;radix_tree_iter_init (&iter, id);
tools/testing/radix-tree/idr-test.c +21 -0
@@ -57,6 +57,26 @@ void idr_alloc_test(void)idr_destroy (&idr); } +void idr_alloc2_test (void ) +{ +int id; +struct idr idr =IDR_INIT_BASE (idr,1 ); + + id =idr_alloc (&idr, idr_alloc2_test,0 ,1 ,GFP_KERNEL ); +assert (id == -ENOSPC ); + + id =idr_alloc (&idr, idr_alloc2_test,1 ,2 ,GFP_KERNEL ); +assert (id ==1 ); + + id =idr_alloc (&idr, idr_alloc2_test,0 ,1 ,GFP_KERNEL ); +assert (id == -ENOSPC ); + + id =idr_alloc (&idr, idr_alloc2_test,0 ,2 ,GFP_KERNEL ); +assert (id == -ENOSPC ); + +idr_destroy (&idr); +} +void idr_replace_test (void ) {DEFINE_IDR (idr);
@@ -409,6 +429,7 @@ void idr_checks(void)idr_replace_test ();idr_alloc_test (); +idr_alloc2_test ();idr_null_test ();idr_nowait_test ();idr_get_next_test (0 );
Greg Kroah-Hartman
maintainerPATCH 401/554 RDMA/core: Check for the presence of LS_NLA_TYPE_DGID correctly
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
commit a7b8e876e0ef0232b8076972c57ce9a7286b47ca upstream.
The netlink response for RDMA_NL_LS_OP_IP_RESOLVE should always have a LS_NLA_TYPE_DGID attribute, it is invalid if it does not.
Use the nl parsing logic properly and call nla_parse_deprecated() to fill the nlattrs array and then directly index that array to get the data for the DGID. Just fail if it is NULL.
Remove the for loop searching for the nla, and squash the validation and parsing into one function.
Fixes an uninitialized read from the stack triggered by userspace if it does not provide the DGID to a kernel initiated RDMA_NL_LS_OP_IP_RESOLVE query.
BUG: KMSAN: uninit-value in hex_byte_pack include/linux/hex.h:13 [inline]
BUG: KMSAN: uninit-value in ip6_string+0xef4/0x13a0 lib/vsprintf.c:1490
hex_byte_pack include/linux/hex.h:13 [inline]
ip6_string+0xef4/0x13a0 lib/vsprintf.c:1490
ip6_addr_string+0x18a/0x3e0 lib/vsprintf.c:1509
ip_addr_string+0x245/0xee0 lib/vsprintf.c:1633
pointer+0xc09/0x1bd0 lib/vsprintf.c:2542
vsnprintf+0xf8a/0x1bd0 lib/vsprintf.c:2930
vprintk_store+0x3ae/0x1530 kernel/printk/printk.c:2279
vprintk_emit+0x307/0xcd0 kernel/printk/printk.c:2426
vprintk_default+0x3f/0x50 kernel/printk/printk.c:2465
vprintk+0x36/0x50 kernel/printk/printk_safe.c:82
_printk+0x17e/0x1b0 kernel/printk/printk.c:2475
ib_nl_process_good_ip_rsep drivers/infiniband/core/addr.c:128 [inline]
ib_nl_handle_ip_res_resp+0x963/0x9d0 drivers/infiniband/core/addr.c:141
rdma_nl_rcv_msg drivers/infiniband/core/netlink.c:-1 [inline]
rdma_nl_rcv_skb drivers/infiniband/core/netlink.c:239 [inline]
rdma_nl_rcv+0xefa/0x11c0 drivers/infiniband/core/netlink.c:259
netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
netlink_unicast+0xf04/0x12b0 net/netlink/af_netlink.c:1346
netlink_sendmsg+0x10b3/0x1250 net/netlink/af_netlink.c:1896
sock_sendmsg_nosec net/socket.c:714 [inline]
__sock_sendmsg+0x333/0x3d0 net/socket.c:729
____sys_sendmsg+0x7e0/0xd80 net/socket.c:2617
___sys_sendmsg+0x271/0x3b0 net/socket.c:2671
__sys_sendmsg+0x1aa/0x300 net/socket.c:2703
__compat_sys_sendmsg net/compat.c:346 [inline]
__do_compat_sys_sendmsg net/compat.c:353 [inline]
__se_compat_sys_sendmsg net/compat.c:350 [inline]
__ia32_compat_sys_sendmsg+0xa4/0x100 net/compat.c:350
ia32_sys_call+0x3f6c/0x4310 arch/x86/include/generated/asm/syscalls_32.h:371
do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline]
__do_fast_syscall_32+0xb0/0x150 arch/x86/entry/syscall_32.c:306
do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:331
do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:3--- drivers/infiniband/core/addr.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-)
drivers/infiniband/core/addr.c +10 -23
@@ -81,37 +81,25 @@ static const struct nla_policy ib_nl_add .min = sizeof(struct rdma_nla_ls_gid)}, }; -static inline bool ib_nl_is_good_ip_resp (const struct nlmsghdr *nlh) +static void ib_nl_process_ip_rsep (const struct nlmsghdr *nlh) {struct nlattr *tb[LS_NLA_TYPE_MAX ] = {}; +union ib_gid gid; +struct addr_req *req; +int found =0 ;int ret;if (nlh->nlmsg_flags &RDMA_NL_LS_F_ERR ) -return false; +return ; ret =nla_parse_deprecated (tb,LS_NLA_TYPE_MAX -1 ,nlmsg_data (nlh),nlmsg_len (nlh), ib_nl_addr_policy,NULL );if (ret) -return false; - -return true; -} - -static void ib_nl_process_good_ip_rsep (const struct nlmsghdr *nlh) -{ -const struct nlattr *head, *curr; -union ib_gid gid; -struct addr_req *req; -int len, rem; -int found =0 ; - - head = (const struct nlattr *)nlmsg_data (nlh); - len =nlmsg_len (nlh); +return ; -nla_for_each_attr (curr, head, len, rem) { -if (curr->nla_type ==LS_NLA_TYPE_DGID ) -memcpy (&gid,nla_data (curr),nla_len (curr)); - } +if (!tb[LS_NLA_TYPE_DGID ]) +return ; +memcpy (&gid,nla_data (tb[LS_NLA_TYPE_DGID ]),sizeof (gid));spin_lock_bh (&lock);list_for_each_entry (req, &req_list, list) {
@@ -138,8 +126,7 @@ int ib_nl_handle_ip_res_resp(struct sk_b !(NETLINK_CB(skb).sk))return -EPERM ; -if (ib_nl_is_good_ip_resp (nlh)) -ib_nl_process_good_ip_rsep (nlh); +ib_nl_process_ip_rsep (nlh);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 402/554 RDMA/cm: Fix leaking the multicast GID table reference
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
commit 57f3cb6c84159d12ba343574df2115fb18dd83ca upstream.
If the CM ID is destroyed while the CM event for multicast creating is still queued the cancel_work_sync() will prevent the work from running which also prevents destroying the ah_attr. This leaks a refcount and triggers a WARN:
GID entry ref leak for dev syz1 index 2 ref=573
WARNING: CPU: 1 PID: 655 at drivers/infiniband/core/cache.c:809 release_gid_table drivers/infiniband/core/cache.c:806 [inline] WARNING: CPU: 1 PID: 655 at drivers/infiniband/core/cache.c:809 gid_table_release_one+0x284/0x3cc drivers/infiniband/core/cache.c:886
Destroy the ah_attr after canceling the work, it is safe to call this twice.
--- drivers/infiniband/core/cma.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/core/cma.c +3 -0
@@ -1836,6 +1836,7 @@ static void destroy_mc(struct rdma_id_prib_sa_free_multicast (mc->sa_mc);if (rdma_protocol_roce (id_priv->id.device, id_priv->id.port_num)) { +struct rdma_cm_event *event = &mc->iboe_join.event;struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;struct net_device *ndev =NULL ;
@@ -1858,6 +1859,8 @@ static void destroy_mc(struct rdma_id_prdev_put (ndev);cancel_work_sync (&mc->iboe_join.work); +if (event->event ==RDMA_CM_EVENT_MULTICAST_JOIN ) +rdma_destroy_ah_attr (&event->param.ud.ah_attr); }kfree (mc); }
Greg Kroah-Hartman
maintainerPATCH 403/554 e1000: fix OOB in e1000_tbi_should_accept()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
commit 9c72a5182ed92904d01057f208c390a303f00a0f upstream.
In e1000_tbi_should_accept() we read the last byte of the frame via 'data[length - 1]' to evaluate the TBI workaround. If the descriptor- reported length is zero or larger than the actual RX buffer size, this read goes out of bounds and can hit unrelated slab objects. The issue is observed from the NAPI receive path (e1000_clean_rx_irq):
==================================================================
BUG: KASAN: slab-out-of-bounds in e1000_tbi_should_accept+0x610/0x790 Read of size 1 at addr ffff888014114e54 by task sshd/363 CPU: 0 PID: 363 Comm: sshd Not tainted 5.18.0-rc1 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 Call Trace: <IRQ> dump_stack_lvl+0x5a/0x74 print_address_description+0x7b/0x440 print_report+0x101/0x200 kasan_report+0xc1/0xf0 e1000_tbi_should_accept+0x610/0x790 e1000_clean_rx_irq+0xa8c/0x1110 e1000_clean+0xde2/0x3c10 __napi_poll+0x98/0x380 net_rx_action+0x491/0xa20 __do_softirq+0x2c9/0x61d do_softirq+0xd1/0x120 </IRQ> <TASK> __local_bh_enable_ip+0xfe/0x130 ip_finish_output2+0x7d5/0xb00 __ip_queue_xmit+0xe24/0x1ab0 __tcp_transmit_skb+0x1bcb/0x3340 tcp_write_xmit+0x175d/0x6bd0 __tcp_push_pending_frames+0x7b/0x280 tcp_sendmsg_locked+0x2e4f/0x32d0 tcp_sendmsg+0x24/0x40 sock_write_iter+0x322/0x430 vfs_write+0x56c/0xa60 ksys_write+0xd1/0x190 do_syscall_64+0x43/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f511b476b10 Code: 73 01 c3 48 8b 0d 88 d3 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d f9 2b 2c 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 8e 9b 01 00 48 89 04 24 RSP: 002b:00007ffc9211d4e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000004024 RCX: 00007f511b476b10 RDX: 0000000000004024 RSI: 0000559a9385962c RDI: 0000000000000003 RBP: 0000559a9383a400 R08: fffffffffffffff0 R09: 0000000000004f00 R10: 0000000000000070 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffc9211d57f R14: 0000559a9347bde7 R15: 0000000000000003 </TASK> Allocated by task 1: __kasan_krealloc+0x131/0x1c0 krealloc+0x90/0xc0 add_sysfs_param+0xcb/0x8a0 kernel_add_sysfs_param+0x81/0xd4 param_sysfs_builtin+0x138/0x1a6 param_sysfs_init+0x57/0x5b do_one_initcall+0x104/0x250 do_initcall_level+0x102/0x132 do_initcalls+0x46/0x74 kernel_init_freeable+0x28f/0x393 kernel_init+0x14/0x1a0 ret_from_fork+0x22/0x30 The buggy address belongs to the object at ffff888014114000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1620 bytes to the right of 2048-byte region [ffff888014114000, ffff888014114800] The buggy address belongs to the physical page: page:ffffea0000504400 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x14110 head:ffffea0000504400 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x100000000010200(slab|head|node=0|zone=1) raw: 0100000000010200 0000000000000000 dead000000000001 ffff888013442000 raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected ==================================================================
This happens because the TBI check unconditionally dereferences the last byte without validating the reported length first:
u8 last_byte = *(data + length - 1);
Fix by rejecting the frame early if the length is zero, or if it exceeds adapter->rx_buffer_len. This preserves the TBI workaround semantics for valid frames and prevents touching memory beyond the RX buffer.
--- drivers/net/ethernet/intel/e1000/e1000_main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/e1000/e1000_main.c +9 -1
@@ -4089,7 +4089,15 @@ static bool e1000_tbi_should_accept(stru u32 length, const u8 *data) { struct e1000_hw *hw = &adapter->hw; -u8 last_byte = *(data + length -1 ); +u8 last_byte; + +/* Guard against OOB on data[length - 1] */ +if (unlikely (!length)) +return false; +/* Upper bound: length must not exceed rx_buffer_len */ +if (unlikely (length > adapter->rx_buffer_len)) +return false; + last_byte = *(data + length -1 );if (TBI_ACCEPT (hw, status, errors, length, last_byte)) {unsigned long irq_flags;
Greg Kroah-Hartman
maintainerPATCH 404/554 fjes: Add missing iounmap in fjes_hw_init()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 15ef641a0c6728d25a400df73922e80ab2cf029c upstream.
In error paths, add fjes_hw_iounmap() to release the resource acquired by fjes_hw_iomap(). Add a goto label to do so.
--- drivers/net/fjes/fjes_hw.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/net/fjes/fjes_hw.c +9 -3
@@ -333,7 +333,7 @@ int fjes_hw_init(struct fjes_hw *hw) ret =fjes_hw_reset (hw);if (ret) -return ret; + goto err_iounmap;fjes_hw_set_irqmask (hw,REG_ICTL_MASK_ALL , true);
@@ -346,8 +346,10 @@ int fjes_hw_init(struct fjes_hw *hw) hw->max_epid =fjes_hw_get_max_epid (hw); hw->my_epid =fjes_hw_get_my_epid (hw); -if ((hw->max_epid ==0 ) || (hw->my_epid >= hw->max_epid)) -return -ENXIO ; +if ((hw->max_epid ==0 ) || (hw->my_epid >= hw->max_epid)) { + ret = -ENXIO ; + goto err_iounmap; + } ret =fjes_hw_setup (hw);
@@ -355,6 +357,10 @@ int fjes_hw_init(struct fjes_hw *hw) hw->hw_info.trace_size =FJES_DEBUG_BUFFER_SIZE ;return ret; + +err_iounmap: +fjes_hw_iounmap (hw); +return ret; }void fjes_hw_exit (struct fjes_hw *hw)
Greg Kroah-Hartman
maintainerPATCH 405/554 nfsd: Drop the client reference in client_states_open()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 1f941b2c23fd34c6f3b76d36f9d0a2528fa92b8f upstream.
In error path, call drop_client() to drop the reference obtained by get_nfsdfs_clp().
--- fs/nfsd/nfs4state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/nfsd/nfs4state.c +3 -1
@@ -2802,8 +2802,10 @@ static int client_states_open(struct inoreturn -ENXIO ; ret =seq_open (file, &states_seq_ops); -if (ret) +if (ret) { +drop_client (clp);return ret; + } s = file->private_data; s->private = clp;return 0 ;
Greg Kroah-Hartman
maintainerPATCH 406/554 net: usb: sr9700: fix incorrect command used to write single register
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Nelson-Moore <[email protected]>
commit fa0b198be1c6775bc7804731a43be5d899d19e7a upstream.
This fixes the device failing to initialize with "error reading MAC address" for me, probably because the incorrect write of NCR_RST to SR_NCR is not actually resetting the device.
--- drivers/net/usb/sr9700.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/usb/sr9700.c +2 -2
@@ -52,7 +52,7 @@ static int sr_read_reg(struct usbnet *destatic int sr_write_reg (struct usbnet *dev,u8 reg,u8 value) { -return usbnet_write_cmd (dev,SR_WR_REGS ,SR_REQ_WR_REG , +return usbnet_write_cmd (dev,SR_WR_REG ,SR_REQ_WR_REG , value, reg,NULL ,0 ); }
@@ -65,7 +65,7 @@ static void sr_write_async(struct usbnetstatic void sr_write_reg_async (struct usbnet *dev,u8 reg,u8 value) { -usbnet_write_cmd_async (dev,SR_WR_REGS ,SR_REQ_WR_REG , +usbnet_write_cmd_async (dev,SR_WR_REG ,SR_REQ_WR_REG , value, reg,NULL ,0 ); }
Greg Kroah-Hartman
maintainerPATCH 407/554 net: nfc: fix deadlock between nfc_unregister_device and rfkill_fop_write
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
commit 1ab526d97a57e44d26fadcc0e9adeb9c0c0182f5 upstream.
A deadlock can occur between nfc_unregister_device() and rfkill_fop_write() due to lock ordering inversion between device_lock and rfkill_global_mutex.
The problematic lock order is:
Thread A (rfkill_fop_write):
rfkill_fop_write()
mutex_lock(&rfkill_global_mutex)
rfkill_set_block()
nfc_rfkill_set_block()
nfc_dev_down()
device_lock(&dev->dev) <- waits for device_lockThread B (nfc_unregister_device):
nfc_unregister_device()
device_lock(&dev->dev)
rfkill_unregister()
mutex_lock(&rfkill_global_mutex) <- waits for rfkill_global_mutex
This creates a classic ABBA deadlock scenario.
Fix this by moving rfkill_unregister() and rfkill_destroy() outside the device_lock critical section. Store the rfkill pointer in a local variable before releasing the lock, then call rfkill_unregister() after releasing device_lock.
This change is safe because rfkill_fop_write() holds rfkill_global_mutex while calling the rfkill callbacks, and rfkill_unregister() also acquires rfkill_global_mutex before cleanup. Therefore, rfkill_unregister() will wait for any ongoing callback to complete before proceeding, and device_del() is only called after rfkill_unregister() returns, preventing any use-after-free.
The similar lock ordering in nfc_register_device() (device_lock -> rfkill_global_mutex via rfkill_register) is safe because during registration the device is not yet in rfkill_list, so no concurrent rfkill operations can occur on this device.
--- net/nfc/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
net/nfc/core.c +7 -2
@@ -1154,6 +1154,7 @@ EXPORT_SYMBOL(nfc_register_device);void nfc_unregister_device (struct nfc_dev *dev) {int rc; +struct rfkill *rfk =NULL ;pr_debug ("dev_name=%s\n" ,dev_name (&dev->dev));
@@ -1164,13 +1165,17 @@ void nfc_unregister_device(struct nfc_dedevice_lock (&dev->dev);if (dev->rfkill) { -rfkill_unregister (dev->rfkill); -rfkill_destroy (dev->rfkill); + rfk = dev->rfkill; dev->rfkill =NULL ; } dev->shutting_down = true;device_unlock (&dev->dev); +if (rfk) { +rfkill_unregister (rfk); +rfkill_destroy (rfk); + } +if (dev->ops->check_presence) {del_timer_sync (&dev->check_pres_timer);cancel_work_sync (&dev->check_pres_work);
Greg Kroah-Hartman
maintainerPATCH 408/554 net: macb: Relocate mog_init_rings() callback from macb_mac_link_up() to macb_open()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaolei Wang <[email protected]>
commit 99537d5c476cada9cf75aef9fa75579a31faadb9 upstream.
In the non-RT kernel, local_bh_disable() merely disables preemption, whereas it maps to an actual spin lock in the RT kernel. Consequently, when attempting to refill RX buffers via netdev_alloc_skb() in macb_mac_link_up(), a deadlock scenario arises as follows:
WARNING: possible circular locking dependency detected 6.18.0-08691-g2061f18ad76e #39 Not tainted
------------------------------------------------------
kworker/0:0/8 is trying to acquire lock:
ffff00080369bbe0 (&bp->lock){+.+.}-{3:3}, at: macb_start_xmit+0x808/0xb7c
but task is already holding lock:
ffff000803698e58 (&queue->tx_ptr_lock){+...}-{3:3}, at: macb_start_xmit +0x148/0xb7c
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (&queue->tx_ptr_lock){+...}-{3:3}:
rt_spin_lock+0x50/0x1f0
macb_start_xmit+0x148/0xb7c
dev_hard_start_xmit+0x94/0x284
sch_direct_xmit+0x8c/0x37c
__dev_queue_xmit+0x708/0x1120
neigh_resolve_output+0x148/0x28c
ip6_finish_output2+0x2c0/0xb2c
__ip6_finish_output+0x114/0x308
ip6_output+0xc4/0x4a4
mld_sendpack+0x220/0x68c
mld_ifc_work+0x2a8/0x4f4
process_one_work+0x20c/0x5f8
worker_thread+0x1b0/0x35c
kthread+0x144/0x200
ret_from_fork+0x10/0x20-> #2 (_xmit_ETHER#2){+...}-{3:3}:
rt_spin_lock+0x50/0x1f0
sch_direct_xmit+0x11c/0x37c
__dev_queue_xmit+0x708/0x1120
neigh_resolve_output+0x148/0x28c
ip6_finish_output2+0x2c0/0xb2c
__ip6_finish_output+0x114/0x308
ip6_output+0xc4/0x4a4
mld_sendpack+0x220/0x68c
mld_ifc_work+0x2a8/0x4f4
process_one_work+0x20c/0x5f8
worker_thread+0x1b0/0x35c
kthread+0x144/0x200
ret_from_fork+0x10/0x20-> #1 ((softirq_ctrl.lock)){+.+.}-{3:3}:
lock_release+0x250/0x348
__local_bh_enable_ip+0x7c/0x240
__netdev_alloc_skb+0x1b4/0x1d8
gem_rx_refill+0xdc/0x240
gem_init_rings+0xb4/0x108
macb_mac_link_up+0x9c/0x2b4
phylink_resolve+0x170/0x614
process_one_work+0x20c/0x5f8
worker_thread+0x1b0/0x35c
kthread+0x144/0x200
ret_from_fork+0x10/0x20-> #0 (&bp->lock){+.+.}-{3:3}:
__lock_acquire+0x15a8/0x2084
lock_acquire+0x1cc/0x350
rt_spin_lock+0x50/0x1f0
macb_start_xmit+0x808/0xb7c
dev_hard_start_xmit+0x94/0x284
sch_direct_xmit+0x8c/0x37c
__dev_queue_xmit+0x708/0x1120
neigh_resolve_output+0x148/0x28c
ip6_finish_output2+0x2c0/0xb2c
__ip6_finish_output+0x114/0x308
ip6_output+0xc4/0x4a4
mld_sendpack+0x220/0x68c
mld_ifc_work+0x2a8/0x4f4
process_one_work+0x20c/0x5f8
worker_thread+0x1b0/0x35c
kthread+0x144/0x200
ret_from_fork+0x10/0x20other info that might help us debug this:
Chain exists of:
&bp->lock --> _xmit_ETHER#2 --> &queue->tx_ptr_lock
Possible unsafe locking scenario: CPU0 CPU1
---- ----
lock(&queue->tx_ptr_lock);
lock(_xmit_ETHER#2);
lock(&queue->tx_ptr_lock);
lock(&bp->lock);
*** DEADLOCK *** Call trace:
show_stack+0x18/0x24 (C)
dump_stack_lvl+0xa0/0xf0
dump_stack+0x18/0x24
print_circular_bug+0x28c/0x370
check_noncircular+0x198/0x1ac
__lock_acquire+0x15a8/0x2084
lock_acquire+0x1cc/0x350
rt_spin_lock+0x50/0x1f0
macb_start_xmit+0x808/0xb7c
dev_hard_start_xmit+0x94/0x284
sch_direct_xmit+0x8c/0x37c
__dev_queue_xmit+0x708/0x1120
neigh_resolve_output+0x148/0x28c
ip6_finish_output2+0x2c0/0xb2c
__ip6_finish_output+0x114/0x308
ip6_output+0xc4/0x4a4
mld_sendpack+0x220/0x68c
mld_ifc_work+0x2a8/0x4f4
process_one_work+0x20c/0x5f8
worker_thread+0x1b0/0x35c
kthread+0x144/0x200
ret_from_fork+0x10/0x20Notably, invoking the mog_init_rings() callback upon link establishment is unnecessary. Instead, we can exclusively call mog_init_rings() within the ndo_open() callback. This adjustment resolves the deadlock issue. Furthermore, since MACB_CAPS_MACB_IS_EMAC cases do not use mog_init_rings() when opening the network interface via at91ether_open(), moving mog_init_rings() to macb_open() also eliminates the MACB_CAPS_MACB_IS_EMAC check.
--- drivers/net/ethernet/cadence/macb_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/cadence/macb_main.c +2 -1
@@ -777,7 +777,6 @@ static void macb_mac_link_up(struct phyl/* Initialize rings & buffers as clearing MACB_BIT(TE) in link down * cleared the pipeline and control registers. */ - bp->macbgem_ops.mog_init_rings (bp);macb_init_buffers (bp);for (q =0 , queue = bp->queues; q < bp->num_queues; ++q, ++queue)
@@ -2478,6 +2477,8 @@ static void gem_init_rings(struct macb *unsigned int q;int i; + bp->macbgem_ops.mog_init_rings (bp); +for (q =0 , queue = bp->queues; q < bp->num_queues; ++q, ++queue) {for (i =0 ; i < bp->tx_ring_size; i++) { desc =macb_tx_desc (queue, i);
Greg Kroah-Hartman
maintainerPATCH 409/554 drm/msm/a6xx: Fix out of bound IO access in a6xx_get_gmu_registers
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil P Oommen <[email protected]>
commit 779b68a5bf2764c8ed3aa800e41ba0d5d007e1e7 upstream.
REG_A6XX_GMU_AO_AHB_FENCE_CTRL register falls under GMU's register range. So, use gmu_write() routines to write to this register.
Patchwork: https://patchwork.freedesktop.org/patch/688993/
Message-ID: <[email protected]>
--- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +1 -1
@@ -794,7 +794,7 @@ static void a6xx_get_gmu_registers(strucreturn ;/* Set the fence to ALLOW mode so we can access the registers */ -gpu_write (gpu,REG_A6XX_GMU_AO_AHB_FENCE_CTRL ,0 ); +gmu_write (&a6xx_gpu->gmu,REG_A6XX_GMU_AO_AHB_FENCE_CTRL ,0 );_a6xx_get_gmu_registers (gpu, a6xx_state, &a6xx_gmu_reglist[2 ], &a6xx_state->gmu_registers[2 ], false);
Greg Kroah-Hartman
maintainerPATCH 410/554 drm/ttm: Avoid NULL pointer deref for evicted BOs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Richter <[email protected]>
commit 491adc6a0f9903c32b05f284df1148de39e8e644 upstream.
It is possible for a BO to exist that is not currently associated with a resource, e.g. because it has been evicted.
When devcoredump tries to read the contents of all BOs for dumping, we need to expect this as well -- in this case, ENODATA is recorded instead of the buffer contents.
--- drivers/gpu/drm/ttm/ttm_bo_vm.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/ttm/ttm_bo_vm.c +6 -0
@@ -427,6 +427,11 @@ int ttm_bo_vm_access(struct vm_area_struif (ret)return ret; +if (!bo->resource) { + ret = -ENODATA ; + goto unlock; + } +switch (bo->resource->mem_type) {case TTM_PL_SYSTEM : fallthrough;
@@ -441,6 +446,7 @@ int ttm_bo_vm_access(struct vm_area_stru ret = -EIO ; } +unlock:ttm_bo_unreserve (bo);return ret;
Greg Kroah-Hartman
maintainerPATCH 411/554 drm/nouveau/dispnv50: Dont call drm_atomic_get_crtc_state() in prepare_fb
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude Paul <[email protected]>
commit 560271e10b2c86e95ea35afa9e79822e4847f07a upstream.
Since we recently started warning about uses of this function after the atomic check phase completes, we've started getting warnings about this in nouveau. It appears a misplaced drm_atomic_get_crtc_state() call has been hiding in our .prepare_fb callback for a while.
So, fix this by adding a new nv50_head_atom_get_new() function and use that in our .prepare_fb callback instead.
--- drivers/gpu/drm/nouveau/dispnv50/atom.h | 13 +++++++++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/dispnv50/atom.h +13 -0
@@ -152,8 +152,21 @@ static inline struct nv50_head_atom * nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) { struct drm_crtc_state *statec = drm_atomic_get_crtc_state(state, crtc); +if (IS_ERR (statec))return (void *)statec; + +return nv50_head_atom (statec); +} + +static inline struct nv50_head_atom * +nv50_head_atom_get_new (struct drm_atomic_state *state,struct drm_crtc *crtc) +{ +struct drm_crtc_state *statec =drm_atomic_get_new_crtc_state (state, crtc); + +if (!statec) +return NULL ; +return nv50_head_atom (statec); }
drivers/gpu/drm/nouveau/dispnv50/wndw.c +1 -1
@@ -565,7 +565,7 @@ nv50_wndw_prepare_fb(struct drm_plane *p asyw->image.offset[0 ] = nvbo->offset;if (wndw->func->prepare) { - asyh =nv50_head_atom_get (asyw->state.state, asyw->state.crtc); + asyh =nv50_head_atom_get_new (asyw->state.state, asyw->state.crtc);if (IS_ERR (asyh))return PTR_ERR (asyh);
Greg Kroah-Hartman
maintainerPATCH 412/554 mm/damon/tests/vaddr-kunit: handle alloc failures in damon_test_split_evenly_fail()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 7890e5b5bb6e386155c6e755fe70e0cdcc77f18e upstream.
damon_test_split_evenly_fail() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/vaddr-test.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
mm/damon/vaddr-test.h +10 -1
@@ -256,7 +256,16 @@ static void damon_test_split_evenly_fail unsigned long start, unsigned long end, unsigned int nr_pieces) { struct damon_target *t = damon_new_target(42); -struct damon_region *r =damon_new_region (start, end); +struct damon_region *r; + +if (!t) +kunit_skip (test,"target alloc fail" ); + + r =damon_new_region (start, end); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t); KUNIT_EXPECT_EQ(test,
Greg Kroah-Hartman
maintainerPATCH 413/554 mm/damon/tests/vaddr-kunit: handle alloc failures on damon_do_test_apply_three_regions()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 2b22d0fcc6320ba29b2122434c1d2f0785fb0a25 upstream.
damon_do_test_apply_three_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/vaddr-test.h | 6 ++++++ 1 file changed, 6 insertions(+)
mm/damon/vaddr-test.h +6 -0
@@ -141,8 +141,14 @@ static void damon_do_test_apply_three_reint i; t =damon_new_target (42 ); +if (!t) +kunit_skip (test,"target alloc fail" );for (i =0 ; i < nr_regions /2 ; i++) { r =damon_new_region (regions[i *2 ], regions[i *2 +1 ]); +if (!r) { +damon_destroy_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t); }damon_add_target (ctx, t);
Greg Kroah-Hartman
maintainerPATCH 414/554 RDMA/core: Fix "KASAN: slab-use-after-free Read in ib_register_device" problem
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
commit d0706bfd3ee40923c001c6827b786a309e2a8713 upstream.
Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc3/0x670 mm/kasan/report.c:521 kasan_report+0xe0/0x110 mm/kasan/report.c:634 strlen+0x93/0xa0 lib/string.c:420 __fortify_strlen include/linux/fortify-string.h:268 [inline] get_kobj_path_length lib/kobject.c:118 [inline] kobject_get_path+0x3f/0x2a0 lib/kobject.c:158 kobject_uevent_env+0x289/0x1870 lib/kobject_uevent.c:545 ib_register_device drivers/infiniband/core/device.c:1472 [inline] ib_register_device+0x8cf/0xe00 drivers/infiniband/core/device.c:1393 rxe_register_device+0x275/0x320 drivers/infiniband/sw/rxe/rxe_verbs.c:1552 rxe_net_add+0x8e/0xe0 drivers/infiniband/sw/rxe/rxe_net.c:550 rxe_newlink+0x70/0x190 drivers/infiniband/sw/rxe/rxe.c:225 nldev_newlink+0x3a3/0x680 drivers/infiniband/core/nldev.c:1796 rdma_nl_rcv_msg+0x387/0x6e0 drivers/infiniband/core/netlink.c:195 rdma_nl_rcv_skb.constprop.0.isra.0+0x2e5/0x450 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] netlink_unicast+0x53a/0x7f0 net/netlink/af_netlink.c:1339 netlink_sendmsg+0x8d1/0xdd0 net/netlink/af_netlink.c:1883 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg net/socket.c:727 [inline] ____sys_sendmsg+0xa95/0xc70 net/socket.c:2566 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2620 __sys_sendmsg+0x16d/0x220 net/socket.c:2652 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
This problem is similar to the problem that the
commit 1d6a9e7449e2 ("RDMA/core: Fix use-after-free when rename device name") fixes.
The root cause is: the function ib_device_rename() renames the name with lock. But in the function kobject_uevent(), this name is accessed without lock protection at the same time.
The solution is to add the lock protection when this name is accessed in the function kobject_uevent().
[ Ajay: Modified to apply on v5.10.y-v6.6.y
ib_device_notify_register() not present in v5.10.y-v6.6.y, so directly added lock for kobject_uevent() ]
--- drivers/infiniband/core/device.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/infiniband/core/device.c +5 -0
@@ -1449,8 +1449,13 @@ int ib_register_device(struct ib_devicereturn ret; }dev_set_uevent_suppress (&device->dev, false); + +down_read (&devices_rwsem); +/* Mark for userspace that device is ready */ kobject_uevent (&device->dev.kobj,KOBJ_ADD ); + +up_read (&devices_rwsem);ib_device_put (device);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 415/554 mm/damon/tests/vaddr-kunit: handle alloc failures on damon_test_split_evenly_succ()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 0a63a0e7570b9b2631dfb8d836dc572709dce39e upstream.
damon_test_split_evenly_succ() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/vaddr-test.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
mm/damon/vaddr-test.h +8 -1
@@ -290,10 +290,17 @@ static void damon_test_split_evenly_succ unsigned long start, unsigned long end, unsigned int nr_pieces) { struct damon_target *t = damon_new_target(42); -struct damon_region *r =damon_new_region (start, end); +struct damon_region *r;unsigned long expected_width = (end - start) / nr_pieces;unsigned long i =0 ; +if (!t) +kunit_skip (test,"target alloc fail" ); + r =damon_new_region (start, end); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);KUNIT_EXPECT_EQ (test,damon_va_evenly_split_region (t, r, nr_pieces),0 );
Greg Kroah-Hartman
maintainerPATCH 416/554 mm/damon/tests/core-kunit: handle allocation failures in damon_test_regions()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit e16fdd4f754048d6e23c56bd8d920b71e41e3777 upstream.
damon_test_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 6 ++++++ 1 file changed, 6 insertions(+)
mm/damon/core-test.h +6 -0
@@ -20,11 +20,17 @@ static void damon_test_regions(struct kustruct damon_target *t; r =damon_new_region (1 ,2 ); +if (!r) +kunit_skip (test,"region alloc fail" );KUNIT_EXPECT_EQ (test,1ul , r->ar.start);KUNIT_EXPECT_EQ (test,2ul , r->ar.end);KUNIT_EXPECT_EQ (test,0u , r->nr_accesses); t =damon_new_target (42 ); +if (!t) { +damon_free_region (r); +kunit_skip (test,"target alloc fail" ); + }KUNIT_EXPECT_EQ (test,0u ,damon_nr_regions (t));damon_add_region (r, t);
Greg Kroah-Hartman
maintainerPATCH 417/554 mm/damon/tests/core-kunit: handle alloc failures on damon_test_split_at()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 5e80d73f22043c59c8ad36452a3253937ed77955 upstream.
damon_test_split_at() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
mm/damon/core-test.h +11 -0
@@ -128,8 +128,19 @@ static void damon_test_split_at(struct kstruct damon_target *t;struct damon_region *r; +if (!c) +kunit_skip (test,"ctx alloc fail" ); t =damon_new_target (42 ); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } r =damon_new_region (0 ,100 ); +if (!r) { +damon_destroy_ctx (c); +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);damon_split_region_at (c, t, r,25 );KUNIT_EXPECT_EQ (test, r->ar.start,0ul );
Greg Kroah-Hartman
maintainerPATCH 418/554 mm/damon/tests/core-kunit: handle alloc failures on dasmon_test_merge_regions_of()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 0998d2757218771c59d5ca59ccf13d1542a38f17 upstream.
damon_test_merge_regions_of() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 6 ++++++ 1 file changed, 6 insertions(+)
mm/damon/core-test.h +6 -0
@@ -209,8 +209,14 @@ static void damon_test_merge_regions_of(int i; t =damon_new_target (42 ); +if (!t) +kunit_skip (test,"target alloc fail" );for (i =0 ; i <ARRAY_SIZE (sa); i++) { r =damon_new_region (sa[i], ea[i]); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + } r->nr_accesses = nrs[i];damon_add_region (r, t); }
Greg Kroah-Hartman
maintainerPATCH 419/554 mm/damon/tests/core-kunit: handle alloc failures on damon_test_merge_two()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 3d443dd29a1db7efa587a4bb0c06a497e13ca9e4 upstream.
damon_test_merge_two() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
mm/damon/core-test.h +10 -0
@@ -161,10 +161,20 @@ static void damon_test_merge_two(structint i; t =damon_new_target (42 ); +if (!t) +kunit_skip (test,"target alloc fail" ); r =damon_new_region (0 ,100 ); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + } r->nr_accesses =10 ;damon_add_region (r, t); r2 =damon_new_region (100 ,300 ); +if (!r2) { +damon_free_target (t); +kunit_skip (test,"second region alloc fail" ); + } r2->nr_accesses =20 ;damon_add_region (r2, t);
Greg Kroah-Hartman
maintainerPATCH 420/554 mm/damon/tests/core-kunit: handle memory failure from damon_test_target()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit fafe953de2c661907c94055a2497c6b8dbfd26f3 upstream.
damon_test_target() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 7 +++++++ 1 file changed, 7 insertions(+)
mm/damon/core-test.h +7 -0
@@ -58,7 +58,14 @@ static void damon_test_target(struct kunstruct damon_ctx *c =damon_new_ctx ();struct damon_target *t; +if (!c) +kunit_skip (test,"ctx alloc fail" ); + t =damon_new_target (42 ); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + }KUNIT_EXPECT_EQ (test,42ul , t->id);KUNIT_EXPECT_EQ (test,0u ,nr_damon_targets (c));
Greg Kroah-Hartman
maintainerPATCH 421/554 mm/damon/tests/core-kunit: handle alloc failures on damon_test_split_regions_of()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit eded254cb69044bd4abde87394ea44909708d7c0 upstream.
damon_test_split_regions_of() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
mm/damon/core-test.h +21 -0
@@ -255,15 +255,36 @@ static void damon_test_split_regions_of(struct damon_target *t;struct damon_region *r; +if (!c) +kunit_skip (test,"ctx alloc fail" ); + t =damon_new_target (42 ); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"target alloc fail" ); + } r =damon_new_region (0 ,22 ); +if (!r) { +damon_destroy_ctx (c); +damon_free_target (t); +kunit_skip (test,"region alloc fail" ); + }damon_add_region (r, t);damon_split_regions_of (c, t,2 );KUNIT_EXPECT_LE (test,damon_nr_regions (t),2u );damon_free_target (t); t =damon_new_target (42 ); +if (!t) { +damon_destroy_ctx (c); +kunit_skip (test,"second target alloc fail" ); + } r =damon_new_region (0 ,220 ); +if (!r) { +damon_destroy_ctx (c); +damon_free_target (t); +kunit_skip (test,"second region alloc fail" ); + }damon_add_region (r, t);damon_split_regions_of (c, t,4 );KUNIT_EXPECT_LE (test,damon_nr_regions (t),4u );
Greg Kroah-Hartman
maintainerPATCH 422/554 mm/damon/tests/core-kunit: handle memory alloc failure from damon_test_aggregate()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit f79f2fc44ebd0ed655239046be3e80e8804b5545 upstream.
damon_test_aggregate() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases.
--- mm/damon/core-test.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
mm/damon/core-test.h +11 -1
@@ -99,12 +99,22 @@ static void damon_test_aggregate(structstruct damon_region *r;int it, ir; -damon_set_targets (ctx, target_ids,3 ); +if (!ctx) +kunit_skip (test,"ctx alloc fail" ); + +if (damon_set_targets (ctx, target_ids,3 )) { +damon_destroy_ctx (ctx); +kunit_skip (test,"target alloc fail" ); + } it =0 ;damon_for_each_target (t, ctx) {for (ir =0 ; ir <3 ; ir++) { r =damon_new_region (saddr[it][ir], eaddr[it][ir]); +if (!r) { +damon_destroy_ctx (ctx); +kunit_skip (test,"region alloc fail" ); + } r->nr_accesses = accesses[it][ir];damon_add_region (r, t); }
Greg Kroah-Hartman
maintainerPATCH 423/554 kbuild: Use CRC32 and a 1MiB dictionary for XZ compressed modules
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Nybo Andersen <[email protected]>
commit fbf5892df21a8ccfcb2fda0fd65bc3169c89ed28 upstream.
Kmod is now (since kmod commit 09c9f8c5df04 ("libkmod: Use kernel decompression when available")) using the kernel decompressor, when loading compressed modules.
However, the kernel XZ decompressor is XZ Embedded, which doesn't handle CRC64 and dictionaries larger than 1MiB.
Use CRC32 and 1MiB dictionary when XZ compressing and installing kernel modules.
--- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/Makefile.modinst +1 -1
@@ -95,7 +95,7 @@ endif quiet_cmd_gzip = GZIP $@ cmd_gzip = $(KGZIP) -n -f $< quiet_cmd_xz = XZ $@ - cmd_xz = $(XZ) --lzma2=dict=2MiB -f $< + cmd_xz = $(XZ) --check=crc32 --lzma2=dict=1MiB -f $< quiet_cmd_zstd = ZSTD $@ cmd_zstd = $(ZSTD) -T0 --rm -f -q $<
Greg Kroah-Hartman
maintainerPATCH 424/554 virtio_console: fix order of fields cols and rows
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maximilian Immanuel Brandtner <[email protected]>
commit 5326ab737a47278dbd16ed3ee7380b26c7056ddd upstream.
According to section 5.3.6.2 (Multiport Device Operation) of the virtio spec(version 1.2) a control buffer with the event VIRTIO_CONSOLE_RESIZE is followed by a virtio_console_resize struct containing cols then rows. The kernel implements this the wrong way around (rows then cols) resulting in the two values being swapped.
Message-Id: <[email protected]>
--- drivers/char/virtio_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/virtio_console.c +1 -1
@@ -1614,8 +1614,8 @@ static void handle_control_message(strucbreak ;case VIRTIO_CONSOLE_RESIZE : {struct { -__virtio16 rows;__virtio16 cols; +__virtio16 rows; } size;if (!is_console_port (port))
Greg Kroah-Hartman
maintainerPATCH 425/554 drm/vmwgfx: Fix a null-ptr access in the cursor snooper
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zack Rusin <[email protected]>
[ Upstream commit 5ac2c0279053a2c5265d46903432fb26ae2d0da2 ]
Check that the resource which is converted to a surface exists before trying to use the cursor snooper on it.
vmw_cmd_res_check allows explicit invalid (SVGA3D_INVALID_ID) identifiers because some svga commands accept SVGA3D_INVALID_ID to mean "no surface", unfortunately functions that accept the actual surfaces as objects might (and in case of the cursor snooper, do not) be able to handle null objects. Make sure that we validate not only the identifier (via the vmw_cmd_res_check) but also check that the actual resource exists before trying to do something with it.
Fixes unchecked null-ptr reference in the snooping code.
--- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +12 -5
@@ -1525,6 +1525,7 @@ static int vmw_cmd_dma(struct vmw_privat SVGA3dCmdHeader *header) {struct vmw_buffer_object *vmw_bo =NULL ; +struct vmw_resource *res;struct vmw_surface *srf =NULL ;VMW_DECLARE_CMD_VAR (*cmd, SVGA3dCmdSurfaceDMA);int ret;
@@ -1560,18 +1561,24 @@ static int vmw_cmd_dma(struct vmw_privat dirty = (cmd->body.transfer ==SVGA3D_WRITE_HOST_VRAM ) ?VMW_RES_DIRTY_SET :0 ; - ret =vmw_cmd_res_check (dev_priv, sw_context, vmw_res_surface, - dirty, user_surface_converter, - &cmd->body.host.sid,NULL ); + ret =vmw_cmd_res_check (dev_priv, sw_context, vmw_res_surface, dirty, + user_surface_converter, &cmd->body.host.sid, +NULL );if (unlikely (ret !=0 )) {if (unlikely (ret != -ERESTARTSYS ))VMW_DEBUG_USER ("could not find surface for DMA.\n" );return ret; } - srf =vmw_res_to_srf (sw_context->res_cache[vmw_res_surface].res); + res = sw_context->res_cache[vmw_res_surface].res; +if (!res) { +VMW_DEBUG_USER ("Invalid DMA surface.\n" ); +return -EINVAL ; + } -vmw_kms_cursor_snoop (srf, sw_context->fp->tfile, &vmw_bo->base, header); + srf =vmw_res_to_srf (res); +vmw_kms_cursor_snoop (srf, sw_context->fp->tfile, &vmw_bo->base, + header);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 426/554 usb: xhci: move link chain bit quirk checks into one helper function.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Neronin <[email protected]>
commit 7476a2215c07703db5e95efaa3fc5b9f957b9417 upstream.
Older 0.95 xHCI hosts and some other specific newer hosts require the chain bit to be set for Link TRBs even if the link TRB is not in the middle of a transfer descriptor (TD).
move the checks for all those cases into one xhci_link_chain_quirk() function to clean up and avoid code duplication.
No functional changes.
[skip renaming chain_links flag, reword commit message -Mathias]
--- drivers/usb/host/xhci-mem.c | 10 ++-------- drivers/usb/host/xhci-ring.c | 8 ++------ drivers/usb/host/xhci.h | 7 +++++-- 3 files changed, 9 insertions(+), 16 deletions(-)
drivers/usb/host/xhci-mem.c +2 -8
@@ -133,10 +133,7 @@ static void xhci_link_rings(struct xhci_if (!ring || !first || !last)return ; -/* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */ - chain_links = !!(xhci_link_trb_quirk (xhci) || - (ring->type ==TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))); + chain_links =xhci_link_chain_quirk (xhci, ring->type); next = ring->enq_seg->next;xhci_link_segments (ring->enq_seg, first, ring->type, chain_links);
@@ -326,10 +323,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_segment *prev;bool chain_links; -/* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */ - chain_links = !!(xhci_link_trb_quirk (xhci) || - (type ==TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))); + chain_links =xhci_link_chain_quirk (xhci, type); prev =xhci_segment_alloc (xhci, cycle_state, max_packet, flags);if (!prev)
drivers/usb/host/xhci-ring.c +2 -6
@@ -250,9 +250,7 @@ static void inc_enq(struct xhci_hcd *xhc* AMD 0.96 host, carry over the chain bit of the previous TRB * (which may mean the chain bit is cleared). */ -if (!(ring->type ==TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST)) && - !xhci_link_trb_quirk (xhci)) { +if (!xhci_link_chain_quirk (xhci, ring->type)) { next->link.control &=cpu_to_le32 (~TRB_CHAIN ); next->link.control |=cpu_to_le32 (chain); }
@@ -3425,9 +3423,7 @@ static int prepare_ring(struct xhci_hcd/* If we're not dealing with 0.95 hardware or isoc rings * on AMD 0.96 host, clear the chain bit. */ -if (!xhci_link_trb_quirk (xhci) && - !(ep_ring->type ==TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))) +if (!xhci_link_chain_quirk (xhci, ep_ring->type)) ep_ring->enqueue->link.control &=cpu_to_le32 (~TRB_CHAIN );else
drivers/usb/host/xhci.h +5 -2
@@ -1768,9 +1768,12 @@ static inline void xhci_write_64(structlo_hi_writeq (val, regs); } -static inline int xhci_link_trb_quirk (struct xhci_hcd *xhci) + +/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */ +static inline bool xhci_link_chain_quirk (struct xhci_hcd *xhci,enum xhci_ring_type type) { -return xhci->quirks &XHCI_LINK_TRB_QUIRK ; +return (xhci->quirks &XHCI_LINK_TRB_QUIRK ) || + (type ==TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST)); }/* xHCI debugging */
Greg Kroah-Hartman
maintainerPATCH 427/554 usb: xhci: Apply the link chain quirk on NEC isoc endpoints
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio <[email protected]>
commit bb0ba4cb1065e87f9cc75db1fa454e56d0894d01 upstream.
Two clearly different specimens of NEC uPD720200 (one with start/stop bug, one without) were seen to cause IOMMU faults after some Missed Service Errors. Faulting address is immediately after a transfer ring segment and patched dynamic debug messages revealed that the MSE was received when waiting for a TD near the end of that segment:
[ 1.041954] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ffa08fe0 [ 1.042120] xhci_hcd: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0005 address=0xffa09000 flags=0x0000] [ 1.042146] xhci_hcd: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0005 address=0xffa09040 flags=0x0000]
It gets even funnier if the next page is a ring segment accessible to the HC. Below, it reports MSE in segment at ff1e8000, plows through a zero-filled page at ff1e9000 and starts reporting events for TRBs in page at ff1ea000 every microframe, instead of jumping to seg ff1e6000.
[ 7.041671] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ff1e8fe0 [ 7.041999] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ff1e8fe0 [ 7.042011] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042028] xhci_hcd: All TDs skipped for slot 1 ep 2. Clear skip flag. [ 7.042134] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042138] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 31 [ 7.042144] xhci_hcd: Looking for event-dma 00000000ff1ea040 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.042259] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042262] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 31 [ 7.042266] xhci_hcd: Looking for event-dma 00000000ff1ea050 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820
At some point completion events change from Isoch Buffer Overrun to Short Packet and the HC finally finds cycle bit mismatch in ff1ec000.
[ 7.098130] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 13 [ 7.098132] xhci_hcd: Looking for event-dma 00000000ff1ecc50 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.098254] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 13 [ 7.098256] xhci_hcd: Looking for event-dma 00000000ff1ecc60 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.098379] xhci_hcd: Overrun event on slot 1 ep 2
It's possible that data from the isochronous device were written to random buffers of pending TDs on other endpoints (either IN or OUT), other devices or even other HCs in the same IOMMU domain.
Lastly, an error from a different USB device on another HC. Was it caused by the above? I don't know, but it may have been. The disk was working without any other issues and generated PCIe traffic to starve the NEC of upstream BW and trigger those MSEs. The two HCs shared one x1 slot by means of a commercial "PCIe splitter" board.
[ 7.162604] usb 10-2: reset SuperSpeed USB device number 3 using xhci_hcd [ 7.178990] sd 9:0:0:0: [sdb] tag#0 UNKNOWN(0x2003) Result: hostbyte=0x07 driverbyte=DRIVER_OK cmd_age=0s [ 7.179001] sd 9:0:0:0: [sdb] tag#0 CDB: opcode=0x28 28 00 04 02 ae 00 00 02 00 00 [ 7.179004] I/O error, dev sdb, sector 67284480 op 0x0:(READ) flags 0x80700 phys_seg 5 prio class 0
Fortunately, it appears that this ridiculous bug is avoided by setting the chain bit of Link TRBs on isochronous rings. Other ancient HCs are known which also expect the bit to be set and they ignore Link TRBs if it's not. Reportedly, 0.95 spec guaranteed that the bit is set.
The bandwidth-starved NEC HC running a 32KB/uframe UVC endpoint reports tens of MSEs per second and runs into the bug within seconds. Chaining Link TRBs allows the same workload to run for many minutes, many times.
No negative side effects seen in UVC recording and UAC playback with a few devices at full speed, high speed and SuperSpeed.
The problem doesn't reproduce on the newer Renesas uPD720201/uPD720202 and on old Etron EJ168 and VIA VL805 (but the VL805 has other bug).
[shorten line length of log snippets in commit messge -Mathias]
--- drivers/usb/host/xhci.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/usb/host/xhci.h +11 -2
@@ -1769,11 +1769,20 @@ static inline void xhci_write_64(struct } -/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */ +/* +* Reportedly, some chapters of v0.95 spec said that Link TRB always has its chain bit set. +* Other chapters and later specs say that it should only be set if the link is inside a TD +* which continues from the end of one segment to the next segment. +* +* Some 0.95 hardware was found to misbehave if any link TRB doesn't have the chain bit set. +* +* 0.96 hardware from AMD and NEC was found to ignore unchained isochronous link TRBs when +* "resynchronizing the pipe" after a Missed Service Error. +*/ static inline bool xhci_link_chain_quirk (struct xhci_hcd *xhci,enum xhci_ring_type type) {return (xhci->quirks &XHCI_LINK_TRB_QUIRK ) || - (type ==TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST)); + (type ==TYPE_ISOC && (xhci->quirks & (XHCI_AMD_0x96_HOST |XHCI_NEC_HOST ))); }/* xHCI debugging */
Greg Kroah-Hartman
maintainerPATCH 428/554 usb: gadget: udc: fix use-after-free in usb_gadget_state_work
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jimmy Hu <[email protected]>
[ Upstream commit baeb66fbd4201d1c4325074e78b1f557dff89b5b ]
A race condition during gadget teardown can lead to a use-after-free in usb_gadget_state_work(), as reported by KASAN:
BUG: KASAN: invalid-access in sysfs_notify+0x2c/0xd0 Workqueue: events usb_gadget_state_work
The fundamental race occurs because a concurrent event (e.g., an interrupt) can call usb_gadget_set_state() and schedule gadget->work at any time during the cleanup process in usb_del_gadget().
Commit 399a45e5237c ("usb: gadget: core: flush gadget workqueue after device removal") attempted to fix this by moving flush_work() to after device_del(). However, this does not fully solve the race, as a new work item can still be scheduled *after* flush_work() completes but before the gadget's memory is freed, leading to the same use-after-free.
This patch fixes the race condition robustly by introducing a 'teardown' flag and a 'state_lock' spinlock to the usb_gadget struct. The flag is set during cleanup in usb_del_gadget() *before* calling flush_work() to prevent any new work from being scheduled once cleanup has commenced. The scheduling site, usb_gadget_set_state(), now checks this flag under the lock before queueing the work, thus safely closing the race window.
--- drivers/usb/gadget/udc/core.c | 17 ++++++++++++++++- include/linux/usb/gadget.h | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-)
drivers/usb/gadget/udc/core.c +16 -1
@@ -1066,8 +1066,13 @@ static void usb_gadget_state_work(structvoid usb_gadget_set_state (struct usb_gadget *gadget,enum usb_device_state state) { +unsigned long flags; + +spin_lock_irqsave (&gadget->state_lock, flags); gadget->state = state; -schedule_work (&gadget->work); +if (!gadget->teardown) +schedule_work (&gadget->work); +spin_unlock_irqrestore (&gadget->state_lock, flags); }EXPORT_SYMBOL_GPL (usb_gadget_set_state);
@@ -1298,6 +1303,8 @@ void usb_initialize_gadget(struct device void (*release)(struct device *dev)) {dev_set_name (&gadget->dev,"gadget" ); +spin_lock_init (&gadget->state_lock); + gadget->teardown = false;INIT_WORK (&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent;
@@ -1478,6 +1485,7 @@ static void usb_gadget_remove_driver(strvoid usb_del_gadget (struct usb_gadget *gadget) {struct usb_udc *udc = gadget->udc; +unsigned long flags;if (!udc)return ;
@@ -1496,6 +1504,13 @@ void usb_del_gadget(struct usb_gadget *gmutex_unlock (&udc_lock);kobject_uevent (&udc->dev.kobj,KOBJ_REMOVE ); +/* +* Set the teardown flag before flushing the work to prevent new work +* from being scheduled while we are cleaning up. +*/ +spin_lock_irqsave (&gadget->state_lock, flags); + gadget->teardown = true; +spin_unlock_irqrestore (&gadget->state_lock, flags);flush_work (&gadget->work);device_unregister (&udc->dev);device_del (&gadget->dev);
include/linux/usb/gadget.h +5 -0
@@ -375,6 +375,9 @@ struct usb_gadget_ops {* can handle. The UDC must support this and all slower speeds and lower * number of lanes. * @state: the state we are now (attached, suspended, configured, etc) +* @state_lock: Spinlock protecting the `state` and `teardown` members. +* @teardown: True if the device is undergoing teardown, used to prevent +* new work from being scheduled during cleanup. * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device.
@@ -449,6 +452,8 @@ struct usb_gadget {enum usb_ssp_rate max_ssp_rate;enum usb_device_state state; +spinlock_t state_lock; +bool teardown;const char *name;struct device dev;unsigned isoch_delay;
Greg Kroah-Hartman
maintainerPATCH 429/554 xhci: dbgtty: use IDR to support several dbc instances.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
[ Upstream commit e1ec140f273e1e30cea7e6d5f50934d877232121 ]
To support systems with several xhci controllers with active dbc on each xhci we need to use IDR to identify and give an index to each port.
Avoid using global struct tty_driver.driver_state for storing dbc port pointer as it won't work with several dbc ports
Stable-dep-of: 1f73b8b56cf3 ("xhci: dbgtty: fix device unregister")
--- drivers/usb/host/xhci-dbgcap.h | 1 drivers/usb/host/xhci-dbgtty.c | 46 ++++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-)
drivers/usb/host/xhci-dbgcap.h +1 -0
@@ -102,6 +102,7 @@ struct dbc_ep {struct dbc_port {struct tty_port port;spinlock_t port_lock;/* port access */ +int minor;struct list_head read_pool;struct list_head read_queue;
drivers/usb/host/xhci-dbgtty.c +39 -7
117 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 430/554 xhci: dbgtty: fix device unregister
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Łukasz Bartosik <[email protected]>
[ Upstream commit 1f73b8b56cf35de29a433aee7bfff26cea98be3f ]
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
@@ -489,6 +489,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 431/554 jbd2: fix the inconsistency between checksum and data in memory for journal sb
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 6abfe107894af7e8ce3a2e120c619d81ee764ad5 ]
Copying the file system while it is mounted as read-only results in a mount failure:
[~]# mkfs.ext4 -F /dev/sdc
[~]# mount /dev/sdc -o ro /mnt/test
[~]# dd if=/dev/sdc of=/dev/sda bs=1M
[~]# mount /dev/sda /mnt/test1
[ 1094.849826] JBD2: journal checksum error [ 1094.850927] EXT4-fs (sda): Could not load journal inode
mount: mount /dev/sda on /mnt/test1 failed: Bad message
The process described above is just an abstracted way I came up with to reproduce the issue. In the actual scenario, the file system was mounted read-only and then copied while it was still mounted. It was found that the mount operation failed. The user intended to verify the data or use it as a backup, and this action was performed during a version upgrade. Above issue may happen as follows:ext4_fill_super
set_journal_csum_feature_set(sb)
if (ext4_has_metadata_csum(sb))
incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3;
if (test_opt(sb, JOURNAL_CHECKSUM)
jbd2_journal_set_features(sbi->s_journal, compat, 0, incompat);
lock_buffer(journal->j_sb_buffer);
sb->s_feature_incompat |= cpu_to_be32(incompat);
//The data in the journal sb was modified, but the checksum was not
updated, so the data remaining in memory has a mismatch between the
data and the checksum.
unlock_buffer(journal->j_sb_buffer);In this case, the journal sb copied over is in a state where the checksum and data are inconsistent, so mounting fails.
To solve the above issue, update the checksum in memory after modifying the journal sb.
Message-ID: <[email protected]>
--- fs/jbd2/journal.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/jbd2/journal.c +14 -0
@@ -2390,6 +2390,12 @@ int jbd2_journal_set_features(journal_t sb->s_feature_compat |=cpu_to_be32 (compat); sb->s_feature_ro_compat |=cpu_to_be32 (ro); sb->s_feature_incompat |=cpu_to_be32 (incompat); +/* +* Update the checksum now so that it is valid even for read-only +* filesystems where jbd2_write_superblock() doesn't get called. +*/ +if (jbd2_journal_has_csum_v2or3 (journal)) + sb->s_checksum =jbd2_superblock_csum (journal, sb);unlock_buffer (journal->j_sb_buffer); journal->j_revoke_records_per_block =journal_revoke_records_per_block (journal);
@@ -2420,9 +2426,17 @@ void jbd2_journal_clear_features(journal sb = journal->j_superblock; +lock_buffer (journal->j_sb_buffer); sb->s_feature_compat &= ~cpu_to_be32 (compat); sb->s_feature_ro_compat &= ~cpu_to_be32 (ro); sb->s_feature_incompat &= ~cpu_to_be32 (incompat); +/* +* Update the checksum now so that it is valid even for read-only +* filesystems where jbd2_write_superblock() doesn't get called. +*/ +if (jbd2_journal_has_csum_v2or3 (journal)) + sb->s_checksum =jbd2_superblock_csum (journal, sb); +unlock_buffer (journal->j_sb_buffer); journal->j_revoke_records_per_block =journal_revoke_records_per_block (journal); }
Greg Kroah-Hartman
maintainerPATCH 432/554 tpm: Cap the number of PCR banks
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <[email protected]>
[ Upstream commit faf07e611dfa464b201223a7253e9dc5ee0f3c9e ]
tpm2_get_pcr_allocation() does not cap any upper limit for the number of banks. Cap the limit to eight banks so that out of bounds values coming from external I/O cause on only limited harm.
--- drivers/char/tpm/tpm-chip.c | 1 - drivers/char/tpm/tpm1-cmd.c | 5 ----- drivers/char/tpm/tpm2-cmd.c | 8 +++----- include/linux/tpm.h | 9 ++++++--- 4 files changed, 9 insertions(+), 14 deletions(-)
drivers/char/tpm/tpm-chip.c +0 -1
@@ -269,7 +269,6 @@ static void tpm_dev_release(struct devickfree (chip->work_space.context_buf);kfree (chip->work_space.session_buf); -kfree (chip->allocated_banks);kfree (chip); }
drivers/char/tpm/tpm1-cmd.c +0 -5
@@ -794,11 +794,6 @@ int tpm1_pm_suspend(struct tpm_chip *chi*/ int tpm1_get_pcr_allocation (struct tpm_chip *chip) { - chip->allocated_banks =kcalloc (1 ,sizeof (*chip->allocated_banks), -GFP_KERNEL ); -if (!chip->allocated_banks) -return -ENOMEM ; - chip->allocated_banks[0 ].alg_id =TPM_ALG_SHA1 ; chip->allocated_banks[0 ].digest_size = hash_digest_size[HASH_ALGO_SHA1 ]; chip->allocated_banks[0 ].crypto_id =HASH_ALGO_SHA1 ;
drivers/char/tpm/tpm2-cmd.c +3 -5
@@ -574,11 +574,9 @@ ssize_t tpm2_get_pcr_allocation(struct t nr_possible_banks =be32_to_cpup ( (__be32 *)&buf.data[TPM_HEADER_SIZE +5 ]); - - chip->allocated_banks =kcalloc (nr_possible_banks, -sizeof (*chip->allocated_banks), -GFP_KERNEL ); -if (!chip->allocated_banks) { +if (nr_possible_banks >TPM2_MAX_PCR_BANKS ) { +pr_err ("tpm: out of bank capacity: %u > %u\n" , + nr_possible_banks,TPM2_MAX_PCR_BANKS ); rc = -ENOMEM ; goto out; }
include/linux/tpm.h +6 -3
@@ -25,7 +25,10 @@#include <crypto/hash_info.h> #define TPM_DIGEST_SIZE 20/* Max TPM v1.2 PCR size */ -#define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE + +#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE +#define TPM2_MAX_PCR_BANKS 8 +#define TPM_MAX_DIGEST_SIZE TPM2_MAX_DIGEST_SIZEstruct tpm_chip ;struct trusted_key_payload ;
@@ -51,7 +54,7 @@ enum tpm_algorithms {struct tpm_digest {u16 alg_id; -u8 digest[TPM_MAX_DIGEST_SIZE ]; +u8 digest[TPM2_MAX_DIGEST_SIZE ]; } __packed;struct tpm_bank_info {
@@ -157,7 +160,7 @@ struct tpm_chip {unsigned int groups_cnt;u32 nr_allocated_banks; -struct tpm_bank_info *allocated_banks; +struct tpm_bank_info allocated_banks[TPM2_MAX_PCR_BANKS ];#ifdef CONFIG_ACPI acpi_handle acpi_dev_handle;char ppi_version[TPM_PPI_VERSION_LEN +1 ];
Greg Kroah-Hartman
maintainerPATCH 433/554 btrfs: dont rewrite ret from inode_permission
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 0185c2292c600993199bc6b1f342ad47a9e8c678 ]
In our user safe ino resolve ioctl we'll just turn any ret into -EACCES from inode_permission(). This is redundant, and could potentially be wrong if we had an ENOMEM in the security layer or some such other error, so simply return the actual return value.
Note: The patch was taken from v5 of fscrypt patchset
(https://lore.kernel.org/linux-btrfs/[email protected]/)
which was handled over time by various people: Omar Sandoval, Sweet Tea Dorminy, Josef Bacik.
--- fs/btrfs/ioctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/btrfs/ioctl.c +1 -3
@@ -2553,10 +2553,8 @@ static int btrfs_search_path_in_tree_use ret =inode_permission (mnt_userns, temp_inode,MAY_READ |MAY_EXEC );iput (temp_inode); -if (ret) { - ret = -EACCES ; +if (ret) goto out_put; - }if (key.offset == upper_limit.objectid)break ;
Greg Kroah-Hartman
maintainerPATCH 434/554 wifi: mt76: Fix DTS power-limits on little endian systems
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Sven Eckelmann (Plasma Cloud)" <[email protected]>
[ Upstream commit 38b845e1f9e810869b0a0b69f202b877b7b7fb12 ]
The power-limits for ru and mcs and stored in the devicetree as bytewise array (often with sizes which are not a multiple of 4). These arrays have a prefix which defines for how many modes a line is applied. This prefix is also only a byte - but the code still tried to fix the endianness of this byte with a be32 operation. As result, loading was mostly failing or was sending completely unexpected values to the firmware.
Since the other rates are also stored in the devicetree as bytewise arrays, just drop the u32 access + be32_to_cpu conversion and directly access them as bytes arrays.
--- drivers/net/wireless/mediatek/mt76/eeprom.c | 37 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-)
drivers/net/wireless/mediatek/mt76/eeprom.c +24 -13
@@ -173,6 +173,19 @@ mt76_get_of_array(struct device_node *npreturn prop->value; } +static const s8 * +mt76_get_of_array_s8 (struct device_node *np,char *name,size_t *len,int min) +{ +struct property *prop =of_find_property (np, name,NULL ); + +if (!prop || !prop->value || prop->length < min) +return NULL ; + + *len = prop->length; + +return prop->value; +} +static struct device_node *mt76_find_channel_node (struct device_node *np,struct ieee80211_channel *chan) {
@@ -212,7 +225,7 @@ mt76_get_txs_delta(struct device_node *n }static void -mt76_apply_array_limit (s8 *pwr,size_t pwr_len,const __be32 *data, +mt76_apply_array_limit (s8 *pwr,size_t pwr_len,const s8 *data,s8 target_power,s8 nss_delta,s8 *max_power) {int i;
@@ -221,15 +234,14 @@ mt76_apply_array_limit(s8 *pwr, size_t preturn ;for (i =0 ; i < pwr_len; i++) { - pwr[i] =min_t (s8, target_power, -be32_to_cpu (data[i]) + nss_delta); + pwr[i] =min_t (s8, target_power, data[i] + nss_delta); *max_power =max (*max_power, pwr[i]); } }static void mt76_apply_multi_array_limit (s8 *pwr,size_t pwr_len,s8 pwr_num, -const __be32 *data,size_t len,s8 target_power, +const s8 *data,size_t len,s8 target_power,s8 nss_delta,s8 *max_power) {int i, cur;
@@ -237,8 +249,7 @@ mt76_apply_multi_array_limit(s8 *pwr, siif (!data)return ; - len /=4 ; - cur =be32_to_cpu (data[0 ]); + cur = data[0 ];for (i =0 ; i < pwr_num; i++) {if (len < pwr_len +1 )break ;
@@ -253,7 +264,7 @@ mt76_apply_multi_array_limit(s8 *pwr, siif (!len)break ; - cur =be32_to_cpu (data[0 ]); + cur = data[0 ]; } }
@@ -264,7 +275,7 @@ s8 mt76_get_rate_power_limits(struct mt7 {struct mt76_dev *dev = phy->dev;struct device_node *np; -const __be32 *val; +const s8 *val;char name[16 ];u32 mcs_rates = dev->drv->mcs_rates;u32 ru_rates =ARRAY_SIZE (dest->ru[0 ]);
@@ -307,21 +318,21 @@ s8 mt76_get_rate_power_limits(struct mt7 txs_delta =mt76_get_txs_delta (np,hweight8 (phy->antenna_mask)); - val =mt76_get_of_array (np,"rates-cck" , &len,ARRAY_SIZE (dest->cck)); + val =mt76_get_of_array_s8 (np,"rates-cck" , &len,ARRAY_SIZE (dest->cck));mt76_apply_array_limit (dest->cck,ARRAY_SIZE (dest->cck), val, target_power, txs_delta, &max_power); - val =mt76_get_of_array (np,"rates-ofdm" , - &len,ARRAY_SIZE (dest->ofdm)); + val =mt76_get_of_array_s8 (np,"rates-ofdm" , + &len,ARRAY_SIZE (dest->ofdm));mt76_apply_array_limit (dest->ofdm,ARRAY_SIZE (dest->ofdm), val, target_power, txs_delta, &max_power); - val =mt76_get_of_array (np,"rates-mcs" , &len, mcs_rates +1 ); + val =mt76_get_of_array_s8 (np,"rates-mcs" , &len, mcs_rates +1 );mt76_apply_multi_array_limit (dest->mcs[0 ],ARRAY_SIZE (dest->mcs[0 ]),ARRAY_SIZE (dest->mcs), val, len, target_power, txs_delta, &max_power); - val =mt76_get_of_array (np,"rates-ru" , &len, ru_rates +1 ); + val =mt76_get_of_array_s8 (np,"rates-ru" , &len, ru_rates +1 );mt76_apply_multi_array_limit (dest->ru[0 ],ARRAY_SIZE (dest->ru[0 ]),ARRAY_SIZE (dest->ru), val, len, target_power, txs_delta, &max_power);