From: Greg Kroah-Hartman Date: Mon, 29 Jul 2024 10:54:36 +0000 (+0200) Subject: 6.10-stable patches X-Git-Tag: v6.1.103~76 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=99f86ee7a18696f10a611366c3ccac187ad43750;p=thirdparty%2Fkernel%2Fstable-queue.git 6.10-stable patches added patches: apparmor-use-kvfree_sensitive-to-free-data-data.patch block-check-bio-alignment-in-blk_mq_submit_bio.patch cifs-fix-potential-null-pointer-use-in-destroy_workqueue-in-init_cifs-error-path.patch cifs-fix-reconnect-with-smb1-unix-extensions.patch cifs-mount-with-unix-mount-option-for-smb1-incorrectly-handled.patch cpufreq-qcom-nvmem-fix-memory-leaks-in-probe-error-paths.patch drivers-soc-xilinx-check-return-status-of-get_api_version.patch ext4-check-dot-and-dotdot-of-dx_root-before-making-dir-indexed.patch ext4-make-sure-the-first-directory-block-is-not-a-hole.patch genirq-set-irqf_cond_oneshot-in-request_irq.patch io_uring-don-t-allow-netpolling-with-setup_iopoll.patch io_uring-fix-lost-getsockopt-completions.patch io_uring-tighten-task-exit-cancellations.patch jbd2-avoid-infinite-transaction-commit-loop.patch jbd2-make-jbd2_journal_get_max_txn_bufs-internal.patch jbd2-precompute-number-of-transaction-descriptor-blocks.patch leds-mt6360-fix-memory-leak-in-mt6360_init_isnk_properties.patch leds-ss4200-convert-pcibios_-return-codes-to-errnos.patch leds-triggers-flush-pending-brightness-before-activating-trigger.patch m68k-amiga-turn-off-warp1260-interrupts-during-boot.patch md-md-bitmap-fix-writing-non-bitmap-pages.patch media-i2c-alvium-move-v4l2_cid_gain-to-v4l2_cid_analog_gain.patch media-imx-pxp-fix-err_ptr-dereference-in-pxp_probe.patch media-ivsc-csi-add-separate-lock-for-v4l2-control-handler.patch media-uvcvideo-fix-integer-overflow-calculating-timestamp.patch task_work-introduce-task_work_cancel-again.patch task_work-s-task_work_cancel-task_work_cancel_func.patch trace-pid_list-change-gfp-flags-in-pid_list_fill_irq.patch udf-avoid-using-corrupted-block-bitmap-buffer.patch wifi-mwifiex-fix-interface-type-change.patch wifi-rtw88-usb-fix-disconnection-after-beacon-loss.patch wifi-rtw88-usb-further-limit-the-tx-aggregation.patch wifi-rtw89-fix-hw-scan-not-aborting-properly.patch --- diff --git a/queue-6.10/apparmor-use-kvfree_sensitive-to-free-data-data.patch b/queue-6.10/apparmor-use-kvfree_sensitive-to-free-data-data.patch new file mode 100644 index 00000000000..2424fa571da --- /dev/null +++ b/queue-6.10/apparmor-use-kvfree_sensitive-to-free-data-data.patch @@ -0,0 +1,48 @@ +From 2bc73505a5cd2a18a7a542022722f136c19e3b87 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Thu, 1 Feb 2024 17:24:48 +0300 +Subject: apparmor: use kvfree_sensitive to free data->data + +From: Fedor Pchelkin + +commit 2bc73505a5cd2a18a7a542022722f136c19e3b87 upstream. + +Inside unpack_profile() data->data is allocated using kvmemdup() so it +should be freed with the corresponding kvfree_sensitive(). + +Also add missing data->data release for rhashtable insertion failure path +in unpack_profile(). + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: e025be0f26d5 ("apparmor: support querying extended trusted helper extra data") +Cc: stable@vger.kernel.org +Signed-off-by: Fedor Pchelkin +Signed-off-by: John Johansen +Signed-off-by: Greg Kroah-Hartman +--- + security/apparmor/policy.c | 2 +- + security/apparmor/policy_unpack.c | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -225,7 +225,7 @@ static void aa_free_data(void *ptr, void + { + struct aa_data *data = ptr; + +- kfree_sensitive(data->data); ++ kvfree_sensitive(data->data, data->size); + kfree_sensitive(data->key); + kfree_sensitive(data); + } +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -1071,6 +1071,7 @@ static struct aa_profile *unpack_profile + + if (rhashtable_insert_fast(profile->data, &data->head, + profile->data->p)) { ++ kvfree_sensitive(data->data, data->size); + kfree_sensitive(data->key); + kfree_sensitive(data); + info = "failed to insert data to table"; diff --git a/queue-6.10/block-check-bio-alignment-in-blk_mq_submit_bio.patch b/queue-6.10/block-check-bio-alignment-in-blk_mq_submit_bio.patch new file mode 100644 index 00000000000..dfbbbfaacbc --- /dev/null +++ b/queue-6.10/block-check-bio-alignment-in-blk_mq_submit_bio.patch @@ -0,0 +1,70 @@ +From 0676c434a99be42f3bacca4adfd27df65edbf903 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Thu, 20 Jun 2024 11:06:31 +0800 +Subject: block: check bio alignment in blk_mq_submit_bio + +From: Ming Lei + +commit 0676c434a99be42f3bacca4adfd27df65edbf903 upstream. + +IO logical block size is one fundamental queue limit, and every IO has +to be aligned with logical block size because our bio split can't deal +with unaligned bio. + +The check has to be done with queue usage counter grabbed because device +reconfiguration may change logical block size, and we can prevent the +reconfiguration from happening by holding queue usage counter. + +logical_block_size stays in the 1st cache line of queue_limits, and this +cache line is always fetched in fast path via bio_may_exceed_limits(), +so IO perf won't be affected by this check. + +Cc: Yi Zhang +Cc: Christoph Hellwig +Cc: Ye Bin +Cc: stable@vger.kernel.org +Signed-off-by: Ming Lei +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20240620030631.3114026-1-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-mq.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -2914,6 +2914,17 @@ static void blk_mq_use_cached_rq(struct + INIT_LIST_HEAD(&rq->queuelist); + } + ++static bool bio_unaligned(const struct bio *bio, struct request_queue *q) ++{ ++ unsigned int bs_mask = queue_logical_block_size(q) - 1; ++ ++ /* .bi_sector of any zero sized bio need to be initialized */ ++ if ((bio->bi_iter.bi_size & bs_mask) || ++ ((bio->bi_iter.bi_sector << SECTOR_SHIFT) & bs_mask)) ++ return true; ++ return false; ++} ++ + /** + * blk_mq_submit_bio - Create and send a request to block device. + * @bio: Bio pointer. +@@ -2966,6 +2977,15 @@ void blk_mq_submit_bio(struct bio *bio) + return; + } + ++ /* ++ * Device reconfiguration may change logical block size, so alignment ++ * check has to be done with queue usage counter held ++ */ ++ if (unlikely(bio_unaligned(bio, q))) { ++ bio_io_error(bio); ++ goto queue_exit; ++ } ++ + if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { + bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); + if (!bio) diff --git a/queue-6.10/cifs-fix-potential-null-pointer-use-in-destroy_workqueue-in-init_cifs-error-path.patch b/queue-6.10/cifs-fix-potential-null-pointer-use-in-destroy_workqueue-in-init_cifs-error-path.patch new file mode 100644 index 00000000000..ad623080f52 --- /dev/null +++ b/queue-6.10/cifs-fix-potential-null-pointer-use-in-destroy_workqueue-in-init_cifs-error-path.patch @@ -0,0 +1,63 @@ +From 193cc89ea0ca1da311877d2b4bb5e9f03bcc82a2 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Sun, 21 Jul 2024 15:45:56 -0500 +Subject: cifs: fix potential null pointer use in destroy_workqueue in init_cifs error path + +From: Steve French + +commit 193cc89ea0ca1da311877d2b4bb5e9f03bcc82a2 upstream. + +Dan Carpenter reported a Smack static checker warning: + fs/smb/client/cifsfs.c:1981 init_cifs() + error: we previously assumed 'serverclose_wq' could be null (see line 1895) + +The patch which introduced the serverclose workqueue used the wrong +oredering in error paths in init_cifs() for freeing it on errors. + +Fixes: 173217bd7336 ("smb3: retrying on failed server close") +Cc: stable@vger.kernel.org +Cc: Ritvik Budhiraja +Reported-by: Dan Carpenter +Reviewed-by: Dan Carpenter +Reviewed-by: David Howells +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/cifsfs.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -1894,12 +1894,12 @@ init_cifs(void) + WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); + if (!serverclose_wq) { + rc = -ENOMEM; +- goto out_destroy_serverclose_wq; ++ goto out_destroy_deferredclose_wq; + } + + rc = cifs_init_inodecache(); + if (rc) +- goto out_destroy_deferredclose_wq; ++ goto out_destroy_serverclose_wq; + + rc = cifs_init_netfs(); + if (rc) +@@ -1967,6 +1967,8 @@ out_destroy_netfs: + cifs_destroy_netfs(); + out_destroy_inodecache: + cifs_destroy_inodecache(); ++out_destroy_serverclose_wq: ++ destroy_workqueue(serverclose_wq); + out_destroy_deferredclose_wq: + destroy_workqueue(deferredclose_wq); + out_destroy_cifsoplockd_wq: +@@ -1977,8 +1979,6 @@ out_destroy_decrypt_wq: + destroy_workqueue(decrypt_wq); + out_destroy_cifsiod_wq: + destroy_workqueue(cifsiod_wq); +-out_destroy_serverclose_wq: +- destroy_workqueue(serverclose_wq); + out_clean_proc: + cifs_proc_clean(); + return rc; diff --git a/queue-6.10/cifs-fix-reconnect-with-smb1-unix-extensions.patch b/queue-6.10/cifs-fix-reconnect-with-smb1-unix-extensions.patch new file mode 100644 index 00000000000..04ae15e9422 --- /dev/null +++ b/queue-6.10/cifs-fix-reconnect-with-smb1-unix-extensions.patch @@ -0,0 +1,62 @@ +From a214384ce26b6111ea8c8d58fa82a1ca63996c38 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Mon, 22 Jul 2024 23:40:08 -0500 +Subject: cifs: fix reconnect with SMB1 UNIX Extensions + +From: Steve French + +commit a214384ce26b6111ea8c8d58fa82a1ca63996c38 upstream. + +When mounting with the SMB1 Unix Extensions (e.g. mounts +to Samba with vers=1.0), reconnects no longer reset the +Unix Extensions (SetFSInfo SET_FILE_UNIX_BASIC) after tcon so most +operations (e.g. stat, ls, open, statfs) will fail continuously +with: + "Operation not supported" +if the connection ever resets (e.g. due to brief network disconnect) + +Cc: stable@vger.kernel.org +Reviewed-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/connect.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -3686,6 +3686,7 @@ error: + } + #endif + ++#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY + /* + * Issue a TREE_CONNECT request. + */ +@@ -3807,11 +3808,25 @@ CIFSTCon(const unsigned int xid, struct + else + tcon->Flags = 0; + cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags); +- } + ++ /* ++ * reset_cifs_unix_caps calls QFSInfo which requires ++ * need_reconnect to be false, but we would not need to call ++ * reset_caps if this were not a reconnect case so must check ++ * need_reconnect flag here. The caller will also clear ++ * need_reconnect when tcon was successful but needed to be ++ * cleared earlier in the case of unix extensions reconnect ++ */ ++ if (tcon->need_reconnect && tcon->unix_ext) { ++ cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name); ++ tcon->need_reconnect = false; ++ reset_cifs_unix_caps(xid, tcon, NULL, NULL); ++ } ++ } + cifs_buf_release(smb_buffer); + return rc; + } ++#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ + + static void delayed_free(struct rcu_head *p) + { diff --git a/queue-6.10/cifs-mount-with-unix-mount-option-for-smb1-incorrectly-handled.patch b/queue-6.10/cifs-mount-with-unix-mount-option-for-smb1-incorrectly-handled.patch new file mode 100644 index 00000000000..095f8fd6100 --- /dev/null +++ b/queue-6.10/cifs-mount-with-unix-mount-option-for-smb1-incorrectly-handled.patch @@ -0,0 +1,53 @@ +From 0e314e452687ce0ec5874e42cdb993a34325d3d2 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Tue, 23 Jul 2024 00:44:48 -0500 +Subject: cifs: mount with "unix" mount option for SMB1 incorrectly handled + +From: Steve French + +commit 0e314e452687ce0ec5874e42cdb993a34325d3d2 upstream. + +Although by default we negotiate CIFS Unix Extensions for SMB1 mounts to +Samba (and they work if the user does not specify "unix" or "posix" or +"linux" on mount), and we do properly handle when a user turns them off +with "nounix" mount parm. But with the changes to the mount API we +broke cases where the user explicitly specifies the "unix" option (or +equivalently "linux" or "posix") on mount with vers=1.0 to Samba or other +servers which support the CIFS Unix Extensions. + + "mount error(95): Operation not supported" + +and logged: + + "CIFS: VFS: Check vers= mount option. SMB3.11 disabled but required for POSIX extensions" + +even though CIFS Unix Extensions are supported for vers=1.0 This patch fixes +the case where the user specifies both "unix" (or equivalently "posix" or +"linux") and "vers=1.0" on mount to a server which supports the +CIFS Unix Extensions. + +Cc: stable@vger.kernel.org +Reviewed-by: David Howells +Reviewed-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/connect.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2614,6 +2614,13 @@ cifs_get_tcon(struct cifs_ses *ses, stru + cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n"); + rc = -EOPNOTSUPP; + goto out_fail; ++ } else if (ses->server->vals->protocol_id == SMB10_PROT_ID) ++ if (cap_unix(ses)) ++ cifs_dbg(FYI, "Unix Extensions requested on SMB1 mount\n"); ++ else { ++ cifs_dbg(VFS, "SMB1 Unix Extensions not supported by server\n"); ++ rc = -EOPNOTSUPP; ++ goto out_fail; + } else { + cifs_dbg(VFS, + "Check vers= mount option. SMB3.11 disabled but required for POSIX extensions\n"); diff --git a/queue-6.10/cpufreq-qcom-nvmem-fix-memory-leaks-in-probe-error-paths.patch b/queue-6.10/cpufreq-qcom-nvmem-fix-memory-leaks-in-probe-error-paths.patch new file mode 100644 index 00000000000..bb0de76d7f1 --- /dev/null +++ b/queue-6.10/cpufreq-qcom-nvmem-fix-memory-leaks-in-probe-error-paths.patch @@ -0,0 +1,60 @@ +From d01c84b97f19f1137211e90b0a910289a560019e Mon Sep 17 00:00:00 2001 +From: Javier Carrasco +Date: Thu, 23 May 2024 23:24:59 +0200 +Subject: cpufreq: qcom-nvmem: fix memory leaks in probe error paths + +From: Javier Carrasco + +commit d01c84b97f19f1137211e90b0a910289a560019e upstream. + +The code refactoring added new error paths between the np device node +allocation and the call to of_node_put(), which leads to memory leaks if +any of those errors occur. + +Add the missing of_node_put() in the error paths that require it. + +Cc: stable@vger.kernel.org +Fixes: 57f2f8b4aa0c ("cpufreq: qcom: Refactor the driver to make it easier to extend") +Signed-off-by: Javier Carrasco +Signed-off-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/qcom-cpufreq-nvmem.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c ++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c +@@ -480,23 +480,30 @@ static int qcom_cpufreq_probe(struct pla + + drv = devm_kzalloc(&pdev->dev, struct_size(drv, cpus, num_possible_cpus()), + GFP_KERNEL); +- if (!drv) ++ if (!drv) { ++ of_node_put(np); + return -ENOMEM; ++ } + + match = pdev->dev.platform_data; + drv->data = match->data; +- if (!drv->data) ++ if (!drv->data) { ++ of_node_put(np); + return -ENODEV; ++ } + + if (drv->data->get_version) { + speedbin_nvmem = of_nvmem_cell_get(np, NULL); +- if (IS_ERR(speedbin_nvmem)) ++ if (IS_ERR(speedbin_nvmem)) { ++ of_node_put(np); + return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), + "Could not get nvmem cell\n"); ++ } + + ret = drv->data->get_version(cpu_dev, + speedbin_nvmem, &pvs_name, drv); + if (ret) { ++ of_node_put(np); + nvmem_cell_put(speedbin_nvmem); + return ret; + } diff --git a/queue-6.10/drivers-soc-xilinx-check-return-status-of-get_api_version.patch b/queue-6.10/drivers-soc-xilinx-check-return-status-of-get_api_version.patch new file mode 100644 index 00000000000..44bcc3911e9 --- /dev/null +++ b/queue-6.10/drivers-soc-xilinx-check-return-status-of-get_api_version.patch @@ -0,0 +1,48 @@ +From 9b003e14801cf85a8cebeddc87bc9fc77100fdce Mon Sep 17 00:00:00 2001 +From: Jay Buddhabhatti +Date: Wed, 15 May 2024 04:23:45 -0700 +Subject: drivers: soc: xilinx: check return status of get_api_version() + +From: Jay Buddhabhatti + +commit 9b003e14801cf85a8cebeddc87bc9fc77100fdce upstream. + +Currently return status is not getting checked for get_api_version +and because of that for x86 arch we are getting below smatch error. + + CC drivers/soc/xilinx/zynqmp_power.o +drivers/soc/xilinx/zynqmp_power.c: In function 'zynqmp_pm_probe': +drivers/soc/xilinx/zynqmp_power.c:295:12: warning: 'pm_api_version' is +used uninitialized [-Wuninitialized] + 295 | if (pm_api_version < ZYNQMP_PM_VERSION) + | ^ + CHECK drivers/soc/xilinx/zynqmp_power.c +drivers/soc/xilinx/zynqmp_power.c:295 zynqmp_pm_probe() error: +uninitialized symbol 'pm_api_version'. + +So, check return status of pm_get_api_version and return error in case +of failure to avoid checking uninitialized pm_api_version variable. + +Fixes: b9b3a8be28b3 ("firmware: xilinx: Remove eemi ops for get_api_version") +Signed-off-by: Jay Buddhabhatti +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240515112345.24673-1-jay.buddhabhatti@amd.com +Signed-off-by: Michal Simek +Signed-off-by: Greg Kroah-Hartman +--- + drivers/soc/xilinx/zynqmp_power.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/soc/xilinx/zynqmp_power.c ++++ b/drivers/soc/xilinx/zynqmp_power.c +@@ -190,7 +190,9 @@ static int zynqmp_pm_probe(struct platfo + u32 pm_api_version; + struct mbox_client *client; + +- zynqmp_pm_get_api_version(&pm_api_version); ++ ret = zynqmp_pm_get_api_version(&pm_api_version); ++ if (ret) ++ return ret; + + /* Check PM API version number */ + if (pm_api_version < ZYNQMP_PM_VERSION) diff --git a/queue-6.10/ext4-check-dot-and-dotdot-of-dx_root-before-making-dir-indexed.patch b/queue-6.10/ext4-check-dot-and-dotdot-of-dx_root-before-making-dir-indexed.patch new file mode 100644 index 00000000000..7f7984beb06 --- /dev/null +++ b/queue-6.10/ext4-check-dot-and-dotdot-of-dx_root-before-making-dir-indexed.patch @@ -0,0 +1,151 @@ +From 50ea741def587a64e08879ce6c6a30131f7111e7 Mon Sep 17 00:00:00 2001 +From: Baokun Li +Date: Tue, 2 Jul 2024 21:23:48 +0800 +Subject: ext4: check dot and dotdot of dx_root before making dir indexed + +From: Baokun Li + +commit 50ea741def587a64e08879ce6c6a30131f7111e7 upstream. + +Syzbot reports a issue as follows: +============================================ +BUG: unable to handle page fault for address: ffffed11022e24fe +PGD 23ffee067 P4D 23ffee067 PUD 0 +Oops: Oops: 0000 [#1] PREEMPT SMP KASAN PTI +CPU: 0 PID: 5079 Comm: syz-executor306 Not tainted 6.10.0-rc5-g55027e689933 #0 +Call Trace: + + make_indexed_dir+0xdaf/0x13c0 fs/ext4/namei.c:2341 + ext4_add_entry+0x222a/0x25d0 fs/ext4/namei.c:2451 + ext4_rename fs/ext4/namei.c:3936 [inline] + ext4_rename2+0x26e5/0x4370 fs/ext4/namei.c:4214 +[...] +============================================ + +The immediate cause of this problem is that there is only one valid dentry +for the block to be split during do_split, so split==0 results in out of +bounds accesses to the map triggering the issue. + + do_split + unsigned split + dx_make_map + count = 1 + split = count/2 = 0; + continued = hash2 == map[split - 1].hash; + ---> map[4294967295] + +The maximum length of a filename is 255 and the minimum block size is 1024, +so it is always guaranteed that the number of entries is greater than or +equal to 2 when do_split() is called. + +But syzbot's crafted image has no dot and dotdot in dir, and the dentry +distribution in dirblock is as follows: + + bus dentry1 hole dentry2 free +|xx--|xx-------------|...............|xx-------------|...............| +0 12 (8+248)=256 268 256 524 (8+256)=264 788 236 1024 + +So when renaming dentry1 increases its name_len length by 1, neither hole +nor free is sufficient to hold the new dentry, and make_indexed_dir() is +called. + +In make_indexed_dir() it is assumed that the first two entries of the +dirblock must be dot and dotdot, so bus and dentry1 are left in dx_root +because they are treated as dot and dotdot, and only dentry2 is moved +to the new leaf block. That's why count is equal to 1. + +Therefore add the ext4_check_dx_root() helper function to add more sanity +checks to dot and dotdot before starting the conversion to avoid the above +issue. + +Reported-by: syzbot+ae688d469e36fb5138d0@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=ae688d469e36fb5138d0 +Fixes: ac27a0ec112a ("[PATCH] ext4: initial copy of files from ext3") +Cc: stable@kernel.org +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20240702132349.2600605-2-libaokun@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/namei.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 51 insertions(+), 5 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2217,6 +2217,52 @@ static int add_dirent_to_buf(handle_t *h + return err ? err : err2; + } + ++static bool ext4_check_dx_root(struct inode *dir, struct dx_root *root) ++{ ++ struct fake_dirent *fde; ++ const char *error_msg; ++ unsigned int rlen; ++ unsigned int blocksize = dir->i_sb->s_blocksize; ++ char *blockend = (char *)root + dir->i_sb->s_blocksize; ++ ++ fde = &root->dot; ++ if (unlikely(fde->name_len != 1)) { ++ error_msg = "invalid name_len for '.'"; ++ goto corrupted; ++ } ++ if (unlikely(strncmp(root->dot_name, ".", fde->name_len))) { ++ error_msg = "invalid name for '.'"; ++ goto corrupted; ++ } ++ rlen = ext4_rec_len_from_disk(fde->rec_len, blocksize); ++ if (unlikely((char *)fde + rlen >= blockend)) { ++ error_msg = "invalid rec_len for '.'"; ++ goto corrupted; ++ } ++ ++ fde = &root->dotdot; ++ if (unlikely(fde->name_len != 2)) { ++ error_msg = "invalid name_len for '..'"; ++ goto corrupted; ++ } ++ if (unlikely(strncmp(root->dotdot_name, "..", fde->name_len))) { ++ error_msg = "invalid name for '..'"; ++ goto corrupted; ++ } ++ rlen = ext4_rec_len_from_disk(fde->rec_len, blocksize); ++ if (unlikely((char *)fde + rlen >= blockend)) { ++ error_msg = "invalid rec_len for '..'"; ++ goto corrupted; ++ } ++ ++ return true; ++ ++corrupted: ++ EXT4_ERROR_INODE(dir, "Corrupt dir, %s, running e2fsck is recommended", ++ error_msg); ++ return false; ++} ++ + /* + * This converts a one block unindexed directory to a 3 block indexed + * directory, and adds the dentry to the indexed directory. +@@ -2251,17 +2297,17 @@ static int make_indexed_dir(handle_t *ha + brelse(bh); + return retval; + } ++ + root = (struct dx_root *) bh->b_data; ++ if (!ext4_check_dx_root(dir, root)) { ++ brelse(bh); ++ return -EFSCORRUPTED; ++ } + + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext4_dir_entry_2 *)((char *)fde + + ext4_rec_len_from_disk(fde->rec_len, blocksize)); +- if ((char *) de >= (((char *) root) + blocksize)) { +- EXT4_ERROR_INODE(dir, "invalid rec_len for '..'"); +- brelse(bh); +- return -EFSCORRUPTED; +- } + len = ((char *) root) + (blocksize - csum_size) - (char *) de; + + /* Allocate new block for the 0th block's dirents */ diff --git a/queue-6.10/ext4-make-sure-the-first-directory-block-is-not-a-hole.patch b/queue-6.10/ext4-make-sure-the-first-directory-block-is-not-a-hole.patch new file mode 100644 index 00000000000..cd2339a8a68 --- /dev/null +++ b/queue-6.10/ext4-make-sure-the-first-directory-block-is-not-a-hole.patch @@ -0,0 +1,85 @@ +From f9ca51596bbfd0f9c386dd1c613c394c78d9e5e6 Mon Sep 17 00:00:00 2001 +From: Baokun Li +Date: Tue, 2 Jul 2024 21:23:49 +0800 +Subject: ext4: make sure the first directory block is not a hole + +From: Baokun Li + +commit f9ca51596bbfd0f9c386dd1c613c394c78d9e5e6 upstream. + +The syzbot constructs a directory that has no dirblock but is non-inline, +i.e. the first directory block is a hole. And no errors are reported when +creating files in this directory in the following flow. + + ext4_mknod + ... + ext4_add_entry + // Read block 0 + ext4_read_dirblock(dir, block, DIRENT) + bh = ext4_bread(NULL, inode, block, 0) + if (!bh && (type == INDEX || type == DIRENT_HTREE)) + // The first directory block is a hole + // But type == DIRENT, so no error is reported. + +After that, we get a directory block without '.' and '..' but with a valid +dentry. This may cause some code that relies on dot or dotdot (such as +make_indexed_dir()) to crash. + +Therefore when ext4_read_dirblock() finds that the first directory block +is a hole report that the filesystem is corrupted and return an error to +avoid loading corrupted data from disk causing something bad. + +Reported-by: syzbot+ae688d469e36fb5138d0@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=ae688d469e36fb5138d0 +Fixes: 4e19d6b65fb4 ("ext4: allow directory holes") +Cc: stable@kernel.org +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20240702132349.2600605-3-libaokun@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/namei.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -151,10 +151,11 @@ static struct buffer_head *__ext4_read_d + + return bh; + } +- if (!bh && (type == INDEX || type == DIRENT_HTREE)) { ++ /* The first directory block must not be a hole. */ ++ if (!bh && (type == INDEX || type == DIRENT_HTREE || block == 0)) { + ext4_error_inode(inode, func, line, block, +- "Directory hole found for htree %s block", +- (type == INDEX) ? "index" : "leaf"); ++ "Directory hole found for htree %s block %u", ++ (type == INDEX) ? "index" : "leaf", block); + return ERR_PTR(-EFSCORRUPTED); + } + if (!bh) +@@ -3129,10 +3130,7 @@ bool ext4_empty_dir(struct inode *inode) + EXT4_ERROR_INODE(inode, "invalid size"); + return false; + } +- /* The first directory block must not be a hole, +- * so treat it as DIRENT_HTREE +- */ +- bh = ext4_read_dirblock(inode, 0, DIRENT_HTREE); ++ bh = ext4_read_dirblock(inode, 0, EITHER); + if (IS_ERR(bh)) + return false; + +@@ -3577,10 +3575,7 @@ static struct buffer_head *ext4_get_firs + struct ext4_dir_entry_2 *de; + unsigned int offset; + +- /* The first directory block must not be a hole, so +- * treat it as DIRENT_HTREE +- */ +- bh = ext4_read_dirblock(inode, 0, DIRENT_HTREE); ++ bh = ext4_read_dirblock(inode, 0, EITHER); + if (IS_ERR(bh)) { + *retval = PTR_ERR(bh); + return NULL; diff --git a/queue-6.10/genirq-set-irqf_cond_oneshot-in-request_irq.patch b/queue-6.10/genirq-set-irqf_cond_oneshot-in-request_irq.patch new file mode 100644 index 00000000000..4594488fd79 --- /dev/null +++ b/queue-6.10/genirq-set-irqf_cond_oneshot-in-request_irq.patch @@ -0,0 +1,46 @@ +From c37927a203fa283950f6045602b9f71328ad786c Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 11 Jul 2024 12:20:04 +0200 +Subject: genirq: Set IRQF_COND_ONESHOT in request_irq() + +From: Rafael J. Wysocki + +commit c37927a203fa283950f6045602b9f71328ad786c upstream. + +The callers of request_irq() don't care about IRQF_ONESHOT because they +don't provide threaded handlers, but if they happen to share the IRQ with +the ACPI SCI, which has a threaded handler and sets IRQF_ONESHOT, +request_irq() will fail for them due to a flags mismatch. + +Address this by making request_irq() add IRQF_COND_ONESHOT to the flags +passed to request_threaded_irq() for all of its callers. + +Fixes: 7a36b901a6eb ("ACPI: OSL: Use a threaded interrupt handler for SCI") +Reported-by: Stefan Seyfried +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Thomas Gleixner +Tested-by: Stefan Seyfried +Cc: stable@vger.kerel.org +Link: https://lore.kernel.org/r/5800834.DvuYhMxLoT@rjwysocki.net +Closes: https://lore.kernel.org/lkml/205bd84a-fe8e-4963-968e-0763285f35ba@message-id.googlemail.com +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/interrupt.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h +index 5c9bdd3ffccc..dac7466de5f3 100644 +--- a/include/linux/interrupt.h ++++ b/include/linux/interrupt.h +@@ -168,7 +168,7 @@ static inline int __must_check + request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, + const char *name, void *dev) + { +- return request_threaded_irq(irq, handler, NULL, flags, name, dev); ++ return request_threaded_irq(irq, handler, NULL, flags | IRQF_COND_ONESHOT, name, dev); + } + + extern int __must_check +-- +2.45.2 + diff --git a/queue-6.10/io_uring-don-t-allow-netpolling-with-setup_iopoll.patch b/queue-6.10/io_uring-don-t-allow-netpolling-with-setup_iopoll.patch new file mode 100644 index 00000000000..4e021bff855 --- /dev/null +++ b/queue-6.10/io_uring-don-t-allow-netpolling-with-setup_iopoll.patch @@ -0,0 +1,34 @@ +From bd44d7e902c2b34c217d3b48874b079760ca7b6e Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Wed, 24 Jul 2024 12:16:17 +0100 +Subject: io_uring: don't allow netpolling with SETUP_IOPOLL + +From: Pavel Begunkov + +commit bd44d7e902c2b34c217d3b48874b079760ca7b6e upstream. + +IORING_SETUP_IOPOLL rings don't have any netpoll handling, let's fail +attempts to register netpolling in this case, there might be people who +will mix up IOPOLL and netpoll. + +Cc: stable@vger.kernel.org +Fixes: ef1186c1a875b ("io_uring: add register/unregister napi function") +Signed-off-by: Pavel Begunkov +Link: https://lore.kernel.org/r/1e7553aee0a8ae4edec6742cd6dd0c1e6914fba8.1721819383.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/napi.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/io_uring/napi.c ++++ b/io_uring/napi.c +@@ -222,6 +222,8 @@ int io_register_napi(struct io_ring_ctx + }; + struct io_uring_napi napi; + ++ if (ctx->flags & IORING_SETUP_IOPOLL) ++ return -EINVAL; + if (copy_from_user(&napi, arg, sizeof(napi))) + return -EFAULT; + if (napi.pad[0] || napi.pad[1] || napi.pad[2] || napi.resv) diff --git a/queue-6.10/io_uring-fix-lost-getsockopt-completions.patch b/queue-6.10/io_uring-fix-lost-getsockopt-completions.patch new file mode 100644 index 00000000000..812df2c5444 --- /dev/null +++ b/queue-6.10/io_uring-fix-lost-getsockopt-completions.patch @@ -0,0 +1,49 @@ +From 24dce1c538a7ceac43f2f97aae8dfd4bb93ea9b9 Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Tue, 16 Jul 2024 19:05:46 +0100 +Subject: io_uring: fix lost getsockopt completions + +From: Pavel Begunkov + +commit 24dce1c538a7ceac43f2f97aae8dfd4bb93ea9b9 upstream. + +There is a report that iowq executed getsockopt never completes. The +reason being that io_uring_cmd_sock() can return a positive result, and +io_uring_cmd() propagates it back to core io_uring, instead of IOU_OK. +In case of io_wq_submit_work(), the request will be dropped without +completing it. + +The offending code was introduced by a hack in +a9c3eda7eada9 ("io_uring: fix submission-failure handling for uring-cmd"), +however it was fine until getsockopt was introduced and started +returning positive results. + +The right solution is to always return IOU_OK, since +e0b23d9953b0c ("io_uring: optimise ltimeout for inline execution"), +we should be able to do it without problems, however for the sake of +backporting and minimising side effects, let's keep returning negative +return codes and otherwise do IOU_OK. + +Link: https://github.com/axboe/liburing/issues/1181 +Cc: stable@vger.kernel.org +Fixes: 8e9fad0e70b7b ("io_uring: Add io_uring command support for sockets") +Signed-off-by: Pavel Begunkov +Reviewed-by: Breno Leitao +Link: https://lore.kernel.org/r/ff349cf0654018189b6077e85feed935f0f8839e.1721149870.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/uring_cmd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/io_uring/uring_cmd.c ++++ b/io_uring/uring_cmd.c +@@ -265,7 +265,7 @@ int io_uring_cmd(struct io_kiocb *req, u + req_set_fail(req); + io_req_uring_cleanup(req, issue_flags); + io_req_set_res(req, ret, 0); +- return ret; ++ return ret < 0 ? ret : IOU_OK; + } + + int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, diff --git a/queue-6.10/io_uring-tighten-task-exit-cancellations.patch b/queue-6.10/io_uring-tighten-task-exit-cancellations.patch new file mode 100644 index 00000000000..f34c616a5dd --- /dev/null +++ b/queue-6.10/io_uring-tighten-task-exit-cancellations.patch @@ -0,0 +1,51 @@ +From f8b632e89a101dae349a7b212c1771d7925f441b Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Wed, 24 Jul 2024 12:16:16 +0100 +Subject: io_uring: tighten task exit cancellations + +From: Pavel Begunkov + +commit f8b632e89a101dae349a7b212c1771d7925f441b upstream. + +io_uring_cancel_generic() should retry if any state changes like a +request is completed, however in case of a task exit it only goes for +another loop and avoids schedule() if any tracked (i.e. REQ_F_INFLIGHT) +request got completed. + +Let's assume we have a non-tracked request executing in iowq and a +tracked request linked to it. Let's also assume +io_uring_cancel_generic() fails to find and cancel the request, i.e. +via io_run_local_work(), which may happen as io-wq has gaps. +Next, the request logically completes, io-wq still hold a ref but queues +it for completion via tw, which happens in +io_uring_try_cancel_requests(). After, right before prepare_to_wait() +io-wq puts the request, grabs the linked one and tries executes it, e.g. +arms polling. Finally the cancellation loop calls prepare_to_wait(), +there are no tw to run, no tracked request was completed, so the +tctx_inflight() check passes and the task is put to indefinite sleep. + +Cc: stable@vger.kernel.org +Fixes: 3f48cf18f886c ("io_uring: unify files and task cancel") +Signed-off-by: Pavel Begunkov +Link: https://lore.kernel.org/r/acac7311f4e02ce3c43293f8f1fda9c705d158f1.1721819383.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/io_uring.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -3071,8 +3071,11 @@ __cold void io_uring_cancel_generic(bool + bool loop = false; + + io_uring_drop_tctx_refs(current); ++ if (!tctx_inflight(tctx, !cancel_all)) ++ break; ++ + /* read completions before cancelations */ +- inflight = tctx_inflight(tctx, !cancel_all); ++ inflight = tctx_inflight(tctx, false); + if (!inflight) + break; + diff --git a/queue-6.10/jbd2-avoid-infinite-transaction-commit-loop.patch b/queue-6.10/jbd2-avoid-infinite-transaction-commit-loop.patch new file mode 100644 index 00000000000..6b003cfee84 --- /dev/null +++ b/queue-6.10/jbd2-avoid-infinite-transaction-commit-loop.patch @@ -0,0 +1,101 @@ +From 27ba5b67312a944576addc4df44ac3b709aabede Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 24 Jun 2024 19:01:19 +0200 +Subject: jbd2: avoid infinite transaction commit loop + +From: Jan Kara + +commit 27ba5b67312a944576addc4df44ac3b709aabede upstream. + +Commit 9f356e5a4f12 ("jbd2: Account descriptor blocks into +t_outstanding_credits") started to account descriptor blocks into +transactions outstanding credits. However it didn't appropriately +decrease the maximum amount of credits available to userspace. Thus if +the filesystem requests a transaction smaller than +j_max_transaction_buffers but large enough that when descriptor blocks +are added the size exceeds j_max_transaction_buffers, we confuse +add_transaction_credits() into thinking previous handles have grown the +transaction too much and enter infinite journal commit loop in +start_this_handle() -> add_transaction_credits() trying to create +transaction with enough credits available. + +Fix the problem by properly accounting for transaction space reserved +for descriptor blocks when verifying requested transaction handle size. + +CC: stable@vger.kernel.org +Fixes: 9f356e5a4f12 ("jbd2: Account descriptor blocks into t_outstanding_credits") +Reported-by: Alexander Coffin +Link: https://lore.kernel.org/all/CA+hUFcuGs04JHZ_WzA1zGN57+ehL2qmHOt5a7RMpo+rv6Vyxtw@mail.gmail.com +Signed-off-by: Jan Kara +Reviewed-by: Zhang Yi +Link: https://patch.msgid.link/20240624170127.3253-3-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/transaction.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -191,6 +191,13 @@ static void sub_reserved_credits(journal + wake_up(&journal->j_wait_reserved); + } + ++/* Maximum number of blocks for user transaction payload */ ++static int jbd2_max_user_trans_buffers(journal_t *journal) ++{ ++ return journal->j_max_transaction_buffers - ++ journal->j_transaction_overhead_buffers; ++} ++ + /* + * Wait until we can add credits for handle to the running transaction. Called + * with j_state_lock held for reading. Returns 0 if handle joined the running +@@ -240,12 +247,12 @@ __must_hold(&journal->j_state_lock) + * big to fit this handle? Wait until reserved credits are freed. + */ + if (atomic_read(&journal->j_reserved_credits) + total > +- journal->j_max_transaction_buffers) { ++ jbd2_max_user_trans_buffers(journal)) { + read_unlock(&journal->j_state_lock); + jbd2_might_wait_for_commit(journal); + wait_event(journal->j_wait_reserved, + atomic_read(&journal->j_reserved_credits) + total <= +- journal->j_max_transaction_buffers); ++ jbd2_max_user_trans_buffers(journal)); + __acquire(&journal->j_state_lock); /* fake out sparse */ + return 1; + } +@@ -285,14 +292,14 @@ __must_hold(&journal->j_state_lock) + + needed = atomic_add_return(rsv_blocks, &journal->j_reserved_credits); + /* We allow at most half of a transaction to be reserved */ +- if (needed > journal->j_max_transaction_buffers / 2) { ++ if (needed > jbd2_max_user_trans_buffers(journal) / 2) { + sub_reserved_credits(journal, rsv_blocks); + atomic_sub(total, &t->t_outstanding_credits); + read_unlock(&journal->j_state_lock); + jbd2_might_wait_for_commit(journal); + wait_event(journal->j_wait_reserved, + atomic_read(&journal->j_reserved_credits) + rsv_blocks +- <= journal->j_max_transaction_buffers / 2); ++ <= jbd2_max_user_trans_buffers(journal) / 2); + __acquire(&journal->j_state_lock); /* fake out sparse */ + return 1; + } +@@ -322,12 +329,12 @@ static int start_this_handle(journal_t * + * size and limit the number of total credits to not exceed maximum + * transaction size per operation. + */ +- if ((rsv_blocks > journal->j_max_transaction_buffers / 2) || +- (rsv_blocks + blocks > journal->j_max_transaction_buffers)) { ++ if (rsv_blocks > jbd2_max_user_trans_buffers(journal) / 2 || ++ rsv_blocks + blocks > jbd2_max_user_trans_buffers(journal)) { + printk(KERN_ERR "JBD2: %s wants too many credits " + "credits:%d rsv_credits:%d max:%d\n", + current->comm, blocks, rsv_blocks, +- journal->j_max_transaction_buffers); ++ jbd2_max_user_trans_buffers(journal)); + WARN_ON(1); + return -ENOSPC; + } diff --git a/queue-6.10/jbd2-make-jbd2_journal_get_max_txn_bufs-internal.patch b/queue-6.10/jbd2-make-jbd2_journal_get_max_txn_bufs-internal.patch new file mode 100644 index 00000000000..2baba1c0cde --- /dev/null +++ b/queue-6.10/jbd2-make-jbd2_journal_get_max_txn_bufs-internal.patch @@ -0,0 +1,66 @@ +From 4aa99c71e42ad60178c1154ec24e3df9c684fb67 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 24 Jun 2024 19:01:17 +0200 +Subject: jbd2: make jbd2_journal_get_max_txn_bufs() internal + +From: Jan Kara + +commit 4aa99c71e42ad60178c1154ec24e3df9c684fb67 upstream. + +There's no reason to have jbd2_journal_get_max_txn_bufs() public +function. Currently all users are internal and can use +journal->j_max_transaction_buffers instead. This saves some unnecessary +recomputations of the limit as a bonus which becomes important as this +function gets more complex in the following patch. + +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Reviewed-by: Zhang Yi +Link: https://patch.msgid.link/20240624170127.3253-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/commit.c | 2 +- + fs/jbd2/journal.c | 5 +++++ + include/linux/jbd2.h | 5 ----- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -766,7 +766,7 @@ start_journal_io: + if (first_block < journal->j_tail) + freed += journal->j_last - journal->j_first; + /* Update tail only if we free significant amount of space */ +- if (freed < jbd2_journal_get_max_txn_bufs(journal)) ++ if (freed < journal->j_max_transaction_buffers) + update_tail = 0; + } + J_ASSERT(commit_transaction->t_state == T_COMMIT); +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1698,6 +1698,11 @@ journal_t *jbd2_journal_init_inode(struc + return journal; + } + ++static int jbd2_journal_get_max_txn_bufs(journal_t *journal) ++{ ++ return (journal->j_total_len - journal->j_fc_wbufsize) / 4; ++} ++ + /* + * Given a journal_t structure, initialise the various fields for + * startup of a new journaling session. We use this both when creating +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -1660,11 +1660,6 @@ int jbd2_wait_inode_data(journal_t *jour + int jbd2_fc_wait_bufs(journal_t *journal, int num_blks); + int jbd2_fc_release_bufs(journal_t *journal); + +-static inline int jbd2_journal_get_max_txn_bufs(journal_t *journal) +-{ +- return (journal->j_total_len - journal->j_fc_wbufsize) / 4; +-} +- + /* + * is_journal_abort + * diff --git a/queue-6.10/jbd2-precompute-number-of-transaction-descriptor-blocks.patch b/queue-6.10/jbd2-precompute-number-of-transaction-descriptor-blocks.patch new file mode 100644 index 00000000000..3d79fa89d36 --- /dev/null +++ b/queue-6.10/jbd2-precompute-number-of-transaction-descriptor-blocks.patch @@ -0,0 +1,197 @@ +From e3a00a23781c1f2fcda98a7aecaac515558e7a35 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 24 Jun 2024 19:01:18 +0200 +Subject: jbd2: precompute number of transaction descriptor blocks + +From: Jan Kara + +commit e3a00a23781c1f2fcda98a7aecaac515558e7a35 upstream. + +Instead of computing the number of descriptor blocks a transaction can +have each time we need it (which is currently when starting each +transaction but will become more frequent later) precompute the number +once during journal initialization together with maximum transaction +size. We perform the precomputation whenever journal feature set is +updated similarly as for computation of +journal->j_revoke_records_per_block. + +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Reviewed-by: Zhang Yi +Link: https://patch.msgid.link/20240624170127.3253-2-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/journal.c | 61 +++++++++++++++++++++++++++++++++++++------------- + fs/jbd2/transaction.c | 24 ------------------- + include/linux/jbd2.h | 7 +++++ + 3 files changed, 54 insertions(+), 38 deletions(-) + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1451,6 +1451,48 @@ static int journal_revoke_records_per_bl + return space / record_size; + } + ++static int jbd2_journal_get_max_txn_bufs(journal_t *journal) ++{ ++ return (journal->j_total_len - journal->j_fc_wbufsize) / 4; ++} ++ ++/* ++ * Base amount of descriptor blocks we reserve for each transaction. ++ */ ++static int jbd2_descriptor_blocks_per_trans(journal_t *journal) ++{ ++ int tag_space = journal->j_blocksize - sizeof(journal_header_t); ++ int tags_per_block; ++ ++ /* Subtract UUID */ ++ tag_space -= 16; ++ if (jbd2_journal_has_csum_v2or3(journal)) ++ tag_space -= sizeof(struct jbd2_journal_block_tail); ++ /* Commit code leaves a slack space of 16 bytes at the end of block */ ++ tags_per_block = (tag_space - 16) / journal_tag_bytes(journal); ++ /* ++ * Revoke descriptors are accounted separately so we need to reserve ++ * space for commit block and normal transaction descriptor blocks. ++ */ ++ return 1 + DIV_ROUND_UP(jbd2_journal_get_max_txn_bufs(journal), ++ tags_per_block); ++} ++ ++/* ++ * Initialize number of blocks each transaction reserves for its bookkeeping ++ * and maximum number of blocks a transaction can use. This needs to be called ++ * after the journal size and the fastcommit area size are initialized. ++ */ ++static void jbd2_journal_init_transaction_limits(journal_t *journal) ++{ ++ journal->j_revoke_records_per_block = ++ journal_revoke_records_per_block(journal); ++ journal->j_transaction_overhead_buffers = ++ jbd2_descriptor_blocks_per_trans(journal); ++ journal->j_max_transaction_buffers = ++ jbd2_journal_get_max_txn_bufs(journal); ++} ++ + /* + * Load the on-disk journal superblock and read the key fields into the + * journal_t. +@@ -1492,8 +1534,8 @@ static int journal_load_superblock(journ + if (jbd2_journal_has_csum_v2or3(journal)) + journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, + sizeof(sb->s_uuid)); +- journal->j_revoke_records_per_block = +- journal_revoke_records_per_block(journal); ++ /* After journal features are set, we can compute transaction limits */ ++ jbd2_journal_init_transaction_limits(journal); + + if (jbd2_has_feature_fast_commit(journal)) { + journal->j_fc_last = be32_to_cpu(sb->s_maxlen); +@@ -1698,11 +1740,6 @@ journal_t *jbd2_journal_init_inode(struc + return journal; + } + +-static int jbd2_journal_get_max_txn_bufs(journal_t *journal) +-{ +- return (journal->j_total_len - journal->j_fc_wbufsize) / 4; +-} +- + /* + * Given a journal_t structure, initialise the various fields for + * startup of a new journaling session. We use this both when creating +@@ -1748,8 +1785,6 @@ static int journal_reset(journal_t *jour + journal->j_commit_sequence = journal->j_transaction_sequence - 1; + journal->j_commit_request = journal->j_commit_sequence; + +- journal->j_max_transaction_buffers = jbd2_journal_get_max_txn_bufs(journal); +- + /* + * Now that journal recovery is done, turn fast commits off here. This + * way, if fast commit was enabled before the crash but if now FS has +@@ -2290,8 +2325,6 @@ jbd2_journal_initialize_fast_commit(jour + journal->j_fc_first = journal->j_last + 1; + journal->j_fc_off = 0; + journal->j_free = journal->j_last - journal->j_first; +- journal->j_max_transaction_buffers = +- jbd2_journal_get_max_txn_bufs(journal); + + return 0; + } +@@ -2379,8 +2412,7 @@ int jbd2_journal_set_features(journal_t + sb->s_feature_ro_compat |= cpu_to_be32(ro); + sb->s_feature_incompat |= cpu_to_be32(incompat); + unlock_buffer(journal->j_sb_buffer); +- journal->j_revoke_records_per_block = +- journal_revoke_records_per_block(journal); ++ jbd2_journal_init_transaction_limits(journal); + + return 1; + #undef COMPAT_FEATURE_ON +@@ -2411,8 +2443,7 @@ void jbd2_journal_clear_features(journal + 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); +- journal->j_revoke_records_per_block = +- journal_revoke_records_per_block(journal); ++ jbd2_journal_init_transaction_limits(journal); + } + EXPORT_SYMBOL(jbd2_journal_clear_features); + +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -63,28 +63,6 @@ void jbd2_journal_free_transaction(trans + } + + /* +- * Base amount of descriptor blocks we reserve for each transaction. +- */ +-static int jbd2_descriptor_blocks_per_trans(journal_t *journal) +-{ +- int tag_space = journal->j_blocksize - sizeof(journal_header_t); +- int tags_per_block; +- +- /* Subtract UUID */ +- tag_space -= 16; +- if (jbd2_journal_has_csum_v2or3(journal)) +- tag_space -= sizeof(struct jbd2_journal_block_tail); +- /* Commit code leaves a slack space of 16 bytes at the end of block */ +- tags_per_block = (tag_space - 16) / journal_tag_bytes(journal); +- /* +- * Revoke descriptors are accounted separately so we need to reserve +- * space for commit block and normal transaction descriptor blocks. +- */ +- return 1 + DIV_ROUND_UP(journal->j_max_transaction_buffers, +- tags_per_block); +-} +- +-/* + * jbd2_get_transaction: obtain a new transaction_t object. + * + * Simply initialise a new transaction. Initialize it in +@@ -109,7 +87,7 @@ static void jbd2_get_transaction(journal + transaction->t_expires = jiffies + journal->j_commit_interval; + atomic_set(&transaction->t_updates, 0); + atomic_set(&transaction->t_outstanding_credits, +- jbd2_descriptor_blocks_per_trans(journal) + ++ journal->j_transaction_overhead_buffers + + atomic_read(&journal->j_reserved_credits)); + atomic_set(&transaction->t_outstanding_revokes, 0); + atomic_set(&transaction->t_handle_count, 0); +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -1086,6 +1086,13 @@ struct journal_s + int j_revoke_records_per_block; + + /** ++ * @j_transaction_overhead: ++ * ++ * Number of blocks each transaction needs for its own bookkeeping ++ */ ++ int j_transaction_overhead_buffers; ++ ++ /** + * @j_commit_interval: + * + * What is the maximum transaction lifetime before we begin a commit? diff --git a/queue-6.10/leds-mt6360-fix-memory-leak-in-mt6360_init_isnk_properties.patch b/queue-6.10/leds-mt6360-fix-memory-leak-in-mt6360_init_isnk_properties.patch new file mode 100644 index 00000000000..72bab76f9b9 --- /dev/null +++ b/queue-6.10/leds-mt6360-fix-memory-leak-in-mt6360_init_isnk_properties.patch @@ -0,0 +1,47 @@ +From e41d574b359ccd8d99be65c6f11502efa2b83136 Mon Sep 17 00:00:00 2001 +From: Javier Carrasco +Date: Tue, 11 Jun 2024 00:40:26 +0200 +Subject: leds: mt6360: Fix memory leak in mt6360_init_isnk_properties() + +From: Javier Carrasco + +commit e41d574b359ccd8d99be65c6f11502efa2b83136 upstream. + +The fwnode_for_each_child_node() loop requires manual intervention to +decrement the child refcount in case of an early return. + +Add the missing calls to fwnode_handle_put(child) to avoid memory leaks +in the error paths. + +Cc: stable@vger.kernel.org +Fixes: 679f8652064b ("leds: Add mt6360 driver") +Signed-off-by: Javier Carrasco +Acked-by: Pavel Machek +Link: https://lore.kernel.org/r/20240611-leds-mt6360-memleak-v1-1-93642eb5011e@gmail.com +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/flash/leds-mt6360.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/leds/flash/leds-mt6360.c ++++ b/drivers/leds/flash/leds-mt6360.c +@@ -643,14 +643,17 @@ static int mt6360_init_isnk_properties(s + + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret || reg > MT6360_LED_ISNK3 || +- priv->leds_active & BIT(reg)) ++ priv->leds_active & BIT(reg)) { ++ fwnode_handle_put(child); + return -EINVAL; ++ } + + ret = fwnode_property_read_u32(child, "color", &color); + if (ret) { + dev_err(priv->dev, + "led %d, no color specified\n", + led->led_no); ++ fwnode_handle_put(child); + return ret; + } + diff --git a/queue-6.10/leds-ss4200-convert-pcibios_-return-codes-to-errnos.patch b/queue-6.10/leds-ss4200-convert-pcibios_-return-codes-to-errnos.patch new file mode 100644 index 00000000000..bb7ce7e97ef --- /dev/null +++ b/queue-6.10/leds-ss4200-convert-pcibios_-return-codes-to-errnos.patch @@ -0,0 +1,55 @@ +From ce068e83976140badb19c7f1307926b4b562fac4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Mon, 27 May 2024 16:27:00 +0300 +Subject: leds: ss4200: Convert PCIBIOS_* return codes to errnos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +commit ce068e83976140badb19c7f1307926b4b562fac4 upstream. + +ich7_lpc_probe() uses pci_read_config_dword() that returns PCIBIOS_* +codes. The error handling code assumes incorrectly it's a normal errno +and checks for < 0. The return code is returned from the probe function +as is but probe functions should return normal errnos. + +Remove < 0 from the check and convert PCIBIOS_* returns code using +pcibios_err_to_errno() into normal errno before returning it. + +Fixes: a328e95b82c1 ("leds: LED driver for Intel NAS SS4200 series (v5)") +Cc: +Signed-off-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20240527132700.14260-1-ilpo.jarvinen@linux.intel.com +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/leds-ss4200.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/leds/leds-ss4200.c ++++ b/drivers/leds/leds-ss4200.c +@@ -356,8 +356,10 @@ static int ich7_lpc_probe(struct pci_dev + + nas_gpio_pci_dev = dev; + status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base); +- if (status) ++ if (status) { ++ status = pcibios_err_to_errno(status); + goto out; ++ } + g_pm_io_base &= 0x00000ff80; + + status = pci_read_config_dword(dev, GPIO_CTRL, &gc); +@@ -369,8 +371,9 @@ static int ich7_lpc_probe(struct pci_dev + } + + status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); +- if (0 > status) { ++ if (status) { + dev_info(&dev->dev, "Unable to read GPIOBASE.\n"); ++ status = pcibios_err_to_errno(status); + goto out; + } + dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base); diff --git a/queue-6.10/leds-triggers-flush-pending-brightness-before-activating-trigger.patch b/queue-6.10/leds-triggers-flush-pending-brightness-before-activating-trigger.patch new file mode 100644 index 00000000000..9222eb0b63e --- /dev/null +++ b/queue-6.10/leds-triggers-flush-pending-brightness-before-activating-trigger.patch @@ -0,0 +1,59 @@ +From ab477b766edd3bfb6321a6e3df4c790612613fae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Thu, 13 Jun 2024 17:24:51 +0200 +Subject: leds: triggers: Flush pending brightness before activating trigger +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit ab477b766edd3bfb6321a6e3df4c790612613fae upstream. + +The race fixed in timer_trig_activate() between a blocking +set_brightness() call and trigger->activate() can affect any trigger. +So move the call to flush_work() into led_trigger_set() where it can +avoid the race for all triggers. + +Fixes: 0db37915d912 ("leds: avoid races with workqueue") +Fixes: 8c0f693c6eff ("leds: avoid flush_work in atomic context") +Cc: stable@vger.kernel.org +Tested-by: Dustin L. Howett +Signed-off-by: Thomas Weißschuh +Link: https://lore.kernel.org/r/20240613-led-trigger-flush-v2-1-f4f970799d77@weissschuh.net +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/led-triggers.c | 6 ++++++ + drivers/leds/trigger/ledtrig-timer.c | 5 ----- + 2 files changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/leds/led-triggers.c ++++ b/drivers/leds/led-triggers.c +@@ -194,6 +194,12 @@ int led_trigger_set(struct led_classdev + spin_unlock(&trig->leddev_list_lock); + led_cdev->trigger = trig; + ++ /* ++ * If "set brightness to 0" is pending in workqueue, ++ * we don't want that to be reordered after ->activate() ++ */ ++ flush_work(&led_cdev->set_brightness_work); ++ + ret = 0; + if (trig->activate) + ret = trig->activate(led_cdev); +--- a/drivers/leds/trigger/ledtrig-timer.c ++++ b/drivers/leds/trigger/ledtrig-timer.c +@@ -110,11 +110,6 @@ static int timer_trig_activate(struct le + led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER; + } + +- /* +- * If "set brightness to 0" is pending in workqueue, we don't +- * want that to be reordered after blink_set() +- */ +- flush_work(&led_cdev->set_brightness_work); + led_blink_set(led_cdev, &led_cdev->blink_delay_on, + &led_cdev->blink_delay_off); + diff --git a/queue-6.10/m68k-amiga-turn-off-warp1260-interrupts-during-boot.patch b/queue-6.10/m68k-amiga-turn-off-warp1260-interrupts-during-boot.patch new file mode 100644 index 00000000000..1232af67aef --- /dev/null +++ b/queue-6.10/m68k-amiga-turn-off-warp1260-interrupts-during-boot.patch @@ -0,0 +1,57 @@ +From 1d8491d3e726984343dd8c3cdbe2f2b47cfdd928 Mon Sep 17 00:00:00 2001 +From: Paolo Pisati +Date: Sat, 1 Jun 2024 17:32:54 +0200 +Subject: m68k: amiga: Turn off Warp1260 interrupts during boot + +From: Paolo Pisati + +commit 1d8491d3e726984343dd8c3cdbe2f2b47cfdd928 upstream. + +On an Amiga 1200 equipped with a Warp1260 accelerator, an interrupt +storm coming from the accelerator board causes the machine to crash in +local_irq_enable() or auto_irq_enable(). Disabling interrupts for the +Warp1260 in amiga_parse_bootinfo() fixes the problem. + +Link: https://lore.kernel.org/r/ZkjwzVwYeQtyAPrL@amaterasu.local +Cc: stable +Signed-off-by: Paolo Pisati +Reviewed-by: Michael Schmitz +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20240601153254.186225-1-p.pisati@gmail.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Greg Kroah-Hartman +--- + arch/m68k/amiga/config.c | 9 +++++++++ + include/uapi/linux/zorro_ids.h | 3 +++ + 2 files changed, 12 insertions(+) + +--- a/arch/m68k/amiga/config.c ++++ b/arch/m68k/amiga/config.c +@@ -180,6 +180,15 @@ int __init amiga_parse_bootinfo(const st + dev->slotsize = be16_to_cpu(cd->cd_SlotSize); + dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr); + dev->boardsize = be32_to_cpu(cd->cd_BoardSize); ++ ++ /* CS-LAB Warp 1260 workaround */ ++ if (be16_to_cpu(dev->rom.er_Manufacturer) == ZORRO_MANUF(ZORRO_PROD_CSLAB_WARP_1260) && ++ dev->rom.er_Product == ZORRO_PROD(ZORRO_PROD_CSLAB_WARP_1260)) { ++ ++ /* turn off all interrupts */ ++ pr_info("Warp 1260 card detected: applying interrupt storm workaround\n"); ++ *(uint32_t *)(dev->boardaddr + 0x1000) = 0xfff; ++ } + } else + pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n"); + #endif /* CONFIG_ZORRO */ +--- a/include/uapi/linux/zorro_ids.h ++++ b/include/uapi/linux/zorro_ids.h +@@ -449,6 +449,9 @@ + #define ZORRO_PROD_VMC_ISDN_BLASTER_Z2 ZORRO_ID(VMC, 0x01, 0) + #define ZORRO_PROD_VMC_HYPERCOM_4 ZORRO_ID(VMC, 0x02, 0) + ++#define ZORRO_MANUF_CSLAB 0x1400 ++#define ZORRO_PROD_CSLAB_WARP_1260 ZORRO_ID(CSLAB, 0x65, 0) ++ + #define ZORRO_MANUF_INFORMATION 0x157C + #define ZORRO_PROD_INFORMATION_ISDN_ENGINE_I ZORRO_ID(INFORMATION, 0x64, 0) + diff --git a/queue-6.10/md-md-bitmap-fix-writing-non-bitmap-pages.patch b/queue-6.10/md-md-bitmap-fix-writing-non-bitmap-pages.patch new file mode 100644 index 00000000000..463845ac6c6 --- /dev/null +++ b/queue-6.10/md-md-bitmap-fix-writing-non-bitmap-pages.patch @@ -0,0 +1,100 @@ +From ab99a87542f194f28e2364a42afbf9fb48b1c724 Mon Sep 17 00:00:00 2001 +From: Ofir Gal +Date: Fri, 7 Jun 2024 10:27:44 +0300 +Subject: md/md-bitmap: fix writing non bitmap pages + +From: Ofir Gal + +commit ab99a87542f194f28e2364a42afbf9fb48b1c724 upstream. + +__write_sb_page() rounds up the io size to the optimal io size if it +doesn't exceed the data offset, but it doesn't check the final size +exceeds the bitmap length. + +For example: +page count - 1 +page size - 4K +data offset - 1M +optimal io size - 256K + +The final io size would be 256K (64 pages) but md_bitmap_storage_alloc() +allocated 1 page, the IO would write 1 valid page and 63 pages that +happens to be allocated afterwards. This leaks memory to the raid device +superblock. + +This issue caused a data transfer failure in nvme-tcp. The network +drivers checks the first page of an IO with sendpage_ok(), it returns +true if the page isn't a slabpage and refcount >= 1. If the page +!sendpage_ok() the network driver disables MSG_SPLICE_PAGES. + +As of now the network layer assumes all the pages of the IO are +sendpage_ok() when MSG_SPLICE_PAGES is on. + +The bitmap pages aren't slab pages, the first page of the IO is +sendpage_ok(), but the additional pages that happens to be allocated +after the bitmap pages might be !sendpage_ok(). That cause +skb_splice_from_iter() to stop the data transfer, in the case below it +hangs 'mdadm --create'. + +The bug is reproducible, in order to reproduce we need nvme-over-tcp +controllers with optimal IO size bigger than PAGE_SIZE. Creating a raid +with bitmap over those devices reproduces the bug. + +In order to simulate large optimal IO size you can use dm-stripe with a +single device. +Script to reproduce the issue on top of brd devices using dm-stripe is +attached below (will be added to blktest). + +I have added some logs to test the theory: +... +md: created bitmap (1 pages) for device md127 +__write_sb_page before md_super_write offset: 16, size: 262144. pfn: 0x53ee +=== __write_sb_page before md_super_write. logging pages === +pfn: 0x53ee, slab: 0 <-- the only page that allocated for the bitmap +pfn: 0x53ef, slab: 1 +pfn: 0x53f0, slab: 0 +pfn: 0x53f1, slab: 0 +pfn: 0x53f2, slab: 0 +pfn: 0x53f3, slab: 1 +... +nvme_tcp: sendpage_ok - pfn: 0x53ee, len: 262144, offset: 0 +skbuff: before sendpage_ok() - pfn: 0x53ee +skbuff: before sendpage_ok() - pfn: 0x53ef +WARNING at net/core/skbuff.c:6848 skb_splice_from_iter+0x142/0x450 +skbuff: !sendpage_ok - pfn: 0x53ef. is_slab: 1, page_count: 1 +... + +Cc: stable@vger.kernel.org +Reviewed-by: Christoph Hellwig +Signed-off-by: Ofir Gal +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20240607072748.3182199-1-ofir.gal@volumez.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/md-bitmap.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -227,6 +227,8 @@ static int __write_sb_page(struct md_rde + struct block_device *bdev; + struct mddev *mddev = bitmap->mddev; + struct bitmap_storage *store = &bitmap->storage; ++ unsigned int bitmap_limit = (bitmap->storage.file_pages - pg_index) << ++ PAGE_SHIFT; + loff_t sboff, offset = mddev->bitmap_info.offset; + sector_t ps = pg_index * PAGE_SIZE / SECTOR_SIZE; + unsigned int size = PAGE_SIZE; +@@ -269,11 +271,9 @@ static int __write_sb_page(struct md_rde + if (size == 0) + /* bitmap runs in to data */ + return -EINVAL; +- } else { +- /* DATA METADATA BITMAP - no problems */ + } + +- md_super_write(mddev, rdev, sboff + ps, (int) size, page); ++ md_super_write(mddev, rdev, sboff + ps, (int)min(size, bitmap_limit), page); + return 0; + } + diff --git a/queue-6.10/media-i2c-alvium-move-v4l2_cid_gain-to-v4l2_cid_analog_gain.patch b/queue-6.10/media-i2c-alvium-move-v4l2_cid_gain-to-v4l2_cid_analog_gain.patch new file mode 100644 index 00000000000..e9fbf49c74a --- /dev/null +++ b/queue-6.10/media-i2c-alvium-move-v4l2_cid_gain-to-v4l2_cid_analog_gain.patch @@ -0,0 +1,51 @@ +From a50a2a3242f35dd551d89a6bad17255a410ba955 Mon Sep 17 00:00:00 2001 +From: Tommaso Merciai +Date: Mon, 10 Jun 2024 10:10:34 +0200 +Subject: media: i2c: alvium: Move V4L2_CID_GAIN to V4L2_CID_ANALOG_GAIN + +From: Tommaso Merciai + +commit a50a2a3242f35dd551d89a6bad17255a410ba955 upstream. + +Into alvium cameras REG_BCRM_GAIN_RW control the analog gain. +Let's use the right V4L2_CID_ANALOGUE_GAIN ctrl. + +Fixes: 0a7af872915e ("media: i2c: Add support for alvium camera") +Cc: stable@vger.kernel.org +Signed-off-by: Tommaso Merciai +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/i2c/alvium-csi2.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/media/i2c/alvium-csi2.c ++++ b/drivers/media/i2c/alvium-csi2.c +@@ -1962,7 +1962,7 @@ static int alvium_g_volatile_ctrl(struct + int val; + + switch (ctrl->id) { +- case V4L2_CID_GAIN: ++ case V4L2_CID_ANALOGUE_GAIN: + val = alvium_get_gain(alvium); + if (val < 0) + return val; +@@ -1994,7 +1994,7 @@ static int alvium_s_ctrl(struct v4l2_ctr + return 0; + + switch (ctrl->id) { +- case V4L2_CID_GAIN: ++ case V4L2_CID_ANALOGUE_GAIN: + ret = alvium_set_ctrl_gain(alvium, ctrl->val); + break; + case V4L2_CID_AUTOGAIN: +@@ -2123,7 +2123,7 @@ static int alvium_ctrl_init(struct alviu + + if (alvium->avail_ft.gain) { + ctrls->gain = v4l2_ctrl_new_std(hdl, ops, +- V4L2_CID_GAIN, ++ V4L2_CID_ANALOGUE_GAIN, + alvium->min_gain, + alvium->max_gain, + alvium->inc_gain, diff --git a/queue-6.10/media-imx-pxp-fix-err_ptr-dereference-in-pxp_probe.patch b/queue-6.10/media-imx-pxp-fix-err_ptr-dereference-in-pxp_probe.patch new file mode 100644 index 00000000000..08c36e936b4 --- /dev/null +++ b/queue-6.10/media-imx-pxp-fix-err_ptr-dereference-in-pxp_probe.patch @@ -0,0 +1,35 @@ +From 57e9ce68ae98551da9c161aaab12b41fe8601856 Mon Sep 17 00:00:00 2001 +From: Harshit Mogalapalli +Date: Tue, 14 May 2024 02:50:38 -0700 +Subject: media: imx-pxp: Fix ERR_PTR dereference in pxp_probe() + +From: Harshit Mogalapalli + +commit 57e9ce68ae98551da9c161aaab12b41fe8601856 upstream. + +devm_regmap_init_mmio() can fail, add a check and bail out in case of +error. + +Fixes: 4e5bd3fdbeb3 ("media: imx-pxp: convert to regmap") +Cc: stable@vger.kernel.org +Signed-off-by: Harshit Mogalapalli +Reviewed-by: Laurent Pinchart +Link: https://lore.kernel.org/r/20240514095038.3464191-1-harshit.m.mogalapalli@oracle.com +Signed-off-by: Laurent Pinchart +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/nxp/imx-pxp.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/media/platform/nxp/imx-pxp.c ++++ b/drivers/media/platform/nxp/imx-pxp.c +@@ -1805,6 +1805,9 @@ static int pxp_probe(struct platform_dev + return PTR_ERR(mmio); + dev->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, + &pxp_regmap_config); ++ if (IS_ERR(dev->regmap)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(dev->regmap), ++ "Failed to init regmap\n"); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) diff --git a/queue-6.10/media-ivsc-csi-add-separate-lock-for-v4l2-control-handler.patch b/queue-6.10/media-ivsc-csi-add-separate-lock-for-v4l2-control-handler.patch new file mode 100644 index 00000000000..e9bc88c85e0 --- /dev/null +++ b/queue-6.10/media-ivsc-csi-add-separate-lock-for-v4l2-control-handler.patch @@ -0,0 +1,69 @@ +From c6be6471004e0e4d10d0514146d8c41550823d63 Mon Sep 17 00:00:00 2001 +From: Wentong Wu +Date: Fri, 7 Jun 2024 21:25:46 +0800 +Subject: media: ivsc: csi: add separate lock for v4l2 control handler + +From: Wentong Wu + +commit c6be6471004e0e4d10d0514146d8c41550823d63 upstream. + +There're possibilities that privacy status change notification happens +in the middle of the ongoing mei command which already takes the command +lock, but v4l2_ctrl_s_ctrl() would also need the same lock prior to this +patch, so this may results in circular locking problem. This patch adds +one dedicated lock for v4l2 control handler to avoid described issue. + +Fixes: 29006e196a56 ("media: pci: intel: ivsc: Add CSI submodule") +Cc: stable@vger.kernel.org # for 6.6 and later +Reported-by: Hao Yao +Signed-off-by: Wentong Wu +Tested-by: Jason Chen +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/pci/intel/ivsc/mei_csi.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/media/pci/intel/ivsc/mei_csi.c ++++ b/drivers/media/pci/intel/ivsc/mei_csi.c +@@ -126,6 +126,8 @@ struct mei_csi { + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *freq_ctrl; + struct v4l2_ctrl *privacy_ctrl; ++ /* lock for v4l2 controls */ ++ struct mutex ctrl_lock; + unsigned int remote_pad; + /* start streaming or not */ + int streaming; +@@ -559,11 +561,13 @@ static int mei_csi_init_controls(struct + u32 max; + int ret; + ++ mutex_init(&csi->ctrl_lock); ++ + ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2); + if (ret) + return ret; + +- csi->ctrl_handler.lock = &csi->lock; ++ csi->ctrl_handler.lock = &csi->ctrl_lock; + + max = ARRAY_SIZE(link_freq_menu_items) - 1; + csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler, +@@ -755,6 +759,7 @@ err_entity: + + err_ctrl_handler: + v4l2_ctrl_handler_free(&csi->ctrl_handler); ++ mutex_destroy(&csi->ctrl_lock); + v4l2_async_nf_unregister(&csi->notifier); + v4l2_async_nf_cleanup(&csi->notifier); + +@@ -774,6 +779,7 @@ static void mei_csi_remove(struct mei_cl + v4l2_async_nf_unregister(&csi->notifier); + v4l2_async_nf_cleanup(&csi->notifier); + v4l2_ctrl_handler_free(&csi->ctrl_handler); ++ mutex_destroy(&csi->ctrl_lock); + v4l2_async_unregister_subdev(&csi->subdev); + v4l2_subdev_cleanup(&csi->subdev); + media_entity_cleanup(&csi->subdev.entity); diff --git a/queue-6.10/media-uvcvideo-fix-integer-overflow-calculating-timestamp.patch b/queue-6.10/media-uvcvideo-fix-integer-overflow-calculating-timestamp.patch new file mode 100644 index 00000000000..63d1ee222b1 --- /dev/null +++ b/queue-6.10/media-uvcvideo-fix-integer-overflow-calculating-timestamp.patch @@ -0,0 +1,136 @@ +From 8676a5e796fa18f55897ca36a94b2adf7f73ebd1 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Mon, 10 Jun 2024 19:17:49 +0000 +Subject: media: uvcvideo: Fix integer overflow calculating timestamp + +From: Ricardo Ribalda + +commit 8676a5e796fa18f55897ca36a94b2adf7f73ebd1 upstream. + +The function uvc_video_clock_update() supports a single SOF overflow. Or +in other words, the maximum difference between the first ant the last +timestamp can be 4096 ticks or 4.096 seconds. + +This results in a maximum value for y2 of: 0x12FBECA00, that overflows +32bits. +y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; + +Extend the size of y2 to u64 to support all its values. + +Without this patch: + # yavta -s 1920x1080 -f YUYV -t 1/5 -c /dev/video0 +Device /dev/v4l/by-id/usb-Shine-Optics_Integrated_Camera_0001-video-index0 opened. +Device `Integrated Camera: Integrated C' on `usb-0000:00:14.0-6' (driver 'uvcvideo') supports video, capture, without mplanes. +Video format set: YUYV (56595559) 1920x1080 (stride 3840) field none buffer size 4147200 +Video format: YUYV (56595559) 1920x1080 (stride 3840) field none buffer size 4147200 +Current frame rate: 1/5 +Setting frame rate to: 1/5 +Frame rate set: 1/5 +8 buffers requested. +length: 4147200 offset: 0 timestamp type/source: mono/SoE +Buffer 0/0 mapped at address 0x7947ea94c000. +length: 4147200 offset: 4149248 timestamp type/source: mono/SoE +Buffer 1/0 mapped at address 0x7947ea557000. +length: 4147200 offset: 8298496 timestamp type/source: mono/SoE +Buffer 2/0 mapped at address 0x7947ea162000. +length: 4147200 offset: 12447744 timestamp type/source: mono/SoE +Buffer 3/0 mapped at address 0x7947e9d6d000. +length: 4147200 offset: 16596992 timestamp type/source: mono/SoE +Buffer 4/0 mapped at address 0x7947e9978000. +length: 4147200 offset: 20746240 timestamp type/source: mono/SoE +Buffer 5/0 mapped at address 0x7947e9583000. +length: 4147200 offset: 24895488 timestamp type/source: mono/SoE +Buffer 6/0 mapped at address 0x7947e918e000. +length: 4147200 offset: 29044736 timestamp type/source: mono/SoE +Buffer 7/0 mapped at address 0x7947e8d99000. +0 (0) [-] none 0 4147200 B 507.554210 508.874282 242.836 fps ts mono/SoE +1 (1) [-] none 2 4147200 B 508.886298 509.074289 0.751 fps ts mono/SoE +2 (2) [-] none 3 4147200 B 509.076362 509.274307 5.261 fps ts mono/SoE +3 (3) [-] none 4 4147200 B 509.276371 509.474336 5.000 fps ts mono/SoE +4 (4) [-] none 5 4147200 B 509.476394 509.674394 4.999 fps ts mono/SoE +5 (5) [-] none 6 4147200 B 509.676506 509.874345 4.997 fps ts mono/SoE +6 (6) [-] none 7 4147200 B 509.876430 510.074370 5.002 fps ts mono/SoE +7 (7) [-] none 8 4147200 B 510.076434 510.274365 5.000 fps ts mono/SoE +8 (0) [-] none 9 4147200 B 510.276421 510.474333 5.000 fps ts mono/SoE +9 (1) [-] none 10 4147200 B 510.476391 510.674429 5.001 fps ts mono/SoE +10 (2) [-] none 11 4147200 B 510.676434 510.874283 4.999 fps ts mono/SoE +11 (3) [-] none 12 4147200 B 510.886264 511.074349 4.766 fps ts mono/SoE +12 (4) [-] none 13 4147200 B 511.070577 511.274304 5.426 fps ts mono/SoE +13 (5) [-] none 14 4147200 B 511.286249 511.474301 4.637 fps ts mono/SoE +14 (6) [-] none 15 4147200 B 511.470542 511.674251 5.426 fps ts mono/SoE +15 (7) [-] none 16 4147200 B 511.672651 511.874337 4.948 fps ts mono/SoE +16 (0) [-] none 17 4147200 B 511.873988 512.074462 4.967 fps ts mono/SoE +17 (1) [-] none 18 4147200 B 512.075982 512.278296 4.951 fps ts mono/SoE +18 (2) [-] none 19 4147200 B 512.282631 512.482423 4.839 fps ts mono/SoE +19 (3) [-] none 20 4147200 B 518.986637 512.686333 0.149 fps ts mono/SoE +20 (4) [-] none 21 4147200 B 518.342709 512.886386 -1.553 fps ts mono/SoE +21 (5) [-] none 22 4147200 B 517.909812 513.090360 -2.310 fps ts mono/SoE +22 (6) [-] none 23 4147200 B 517.590775 513.294454 -3.134 fps ts mono/SoE +23 (7) [-] none 24 4147200 B 513.298465 513.494335 -0.233 fps ts mono/SoE +24 (0) [-] none 25 4147200 B 513.510273 513.698375 4.721 fps ts mono/SoE +25 (1) [-] none 26 4147200 B 513.698904 513.902327 5.301 fps ts mono/SoE +26 (2) [-] none 27 4147200 B 513.895971 514.102348 5.074 fps ts mono/SoE +27 (3) [-] none 28 4147200 B 514.099091 514.306337 4.923 fps ts mono/SoE +28 (4) [-] none 29 4147200 B 514.310348 514.510567 4.734 fps ts mono/SoE +29 (5) [-] none 30 4147200 B 514.509295 514.710367 5.026 fps ts mono/SoE +30 (6) [-] none 31 4147200 B 521.532513 514.914398 0.142 fps ts mono/SoE +31 (7) [-] none 32 4147200 B 520.885277 515.118385 -1.545 fps ts mono/SoE +32 (0) [-] none 33 4147200 B 520.411140 515.318336 -2.109 fps ts mono/SoE +33 (1) [-] none 34 4147200 B 515.325425 515.522278 -0.197 fps ts mono/SoE +34 (2) [-] none 35 4147200 B 515.538276 515.726423 4.698 fps ts mono/SoE +35 (3) [-] none 36 4147200 B 515.720767 515.930373 5.480 fps ts mono/SoE + +Cc: stable@vger.kernel.org +Fixes: 66847ef013cc ("[media] uvcvideo: Add UVC timestamps support") +Signed-off-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Link: https://lore.kernel.org/r/20240610-hwtimestamp-followup-v1-2-f9eaed7be7f0@chromium.org +Signed-off-by: Laurent Pinchart +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/uvc/uvc_video.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -720,11 +720,11 @@ void uvc_video_clock_update(struct uvc_s + unsigned long flags; + u64 timestamp; + u32 delta_stc; +- u32 y1, y2; ++ u32 y1; + u32 x1, x2; + u32 mean; + u32 sof; +- u64 y; ++ u64 y, y2; + + if (!uvc_hw_timestamps_param) + return; +@@ -764,7 +764,7 @@ void uvc_video_clock_update(struct uvc_s + sof = y; + + uvc_dbg(stream->dev, CLOCK, +- "%s: PTS %u y %llu.%06llu SOF %u.%06llu (x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n", ++ "%s: PTS %u y %llu.%06llu SOF %u.%06llu (x1 %u x2 %u y1 %u y2 %llu SOF offset %u)\n", + stream->dev->name, buf->pts, + y >> 16, div_u64((y & 0xffff) * 1000000, 65536), + sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), +@@ -779,7 +779,7 @@ void uvc_video_clock_update(struct uvc_s + goto done; + + y1 = NSEC_PER_SEC; +- y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; ++ y2 = ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; + + /* + * Interpolated and host SOF timestamps can wrap around at slightly +@@ -800,7 +800,7 @@ void uvc_video_clock_update(struct uvc_s + timestamp = ktime_to_ns(first->host_time) + y - y1; + + uvc_dbg(stream->dev, CLOCK, +- "%s: SOF %u.%06llu y %llu ts %llu buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n", ++ "%s: SOF %u.%06llu y %llu ts %llu buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %llu)\n", + stream->dev->name, + sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), + y, timestamp, vbuf->vb2_buf.timestamp, diff --git a/queue-6.10/series b/queue-6.10/series index 28acdcb52b6..1a2a5a86fbf 100644 --- a/queue-6.10/series +++ b/queue-6.10/series @@ -580,3 +580,36 @@ drm-gma500-fix-null-pointer-dereference-in-psb_intel_lvds_get_modes.patch drm-amd-display-fix-corruption-with-high-refresh-rates-on-dcn-3.0.patch scsi-qla2xxx-fix-optrom-version-displayed-in-fdmi.patch drm-amd-display-check-for-null-pointer.patch +apparmor-use-kvfree_sensitive-to-free-data-data.patch +cifs-fix-potential-null-pointer-use-in-destroy_workqueue-in-init_cifs-error-path.patch +cifs-fix-reconnect-with-smb1-unix-extensions.patch +cifs-mount-with-unix-mount-option-for-smb1-incorrectly-handled.patch +task_work-s-task_work_cancel-task_work_cancel_func.patch +task_work-introduce-task_work_cancel-again.patch +udf-avoid-using-corrupted-block-bitmap-buffer.patch +m68k-amiga-turn-off-warp1260-interrupts-during-boot.patch +block-check-bio-alignment-in-blk_mq_submit_bio.patch +ext4-check-dot-and-dotdot-of-dx_root-before-making-dir-indexed.patch +ext4-make-sure-the-first-directory-block-is-not-a-hole.patch +io_uring-fix-lost-getsockopt-completions.patch +io_uring-tighten-task-exit-cancellations.patch +io_uring-don-t-allow-netpolling-with-setup_iopoll.patch +trace-pid_list-change-gfp-flags-in-pid_list_fill_irq.patch +genirq-set-irqf_cond_oneshot-in-request_irq.patch +wifi-mwifiex-fix-interface-type-change.patch +wifi-rtw89-fix-hw-scan-not-aborting-properly.patch +wifi-rtw88-usb-fix-disconnection-after-beacon-loss.patch +wifi-rtw88-usb-further-limit-the-tx-aggregation.patch +cpufreq-qcom-nvmem-fix-memory-leaks-in-probe-error-paths.patch +drivers-soc-xilinx-check-return-status-of-get_api_version.patch +leds-ss4200-convert-pcibios_-return-codes-to-errnos.patch +md-md-bitmap-fix-writing-non-bitmap-pages.patch +leds-triggers-flush-pending-brightness-before-activating-trigger.patch +leds-mt6360-fix-memory-leak-in-mt6360_init_isnk_properties.patch +media-ivsc-csi-add-separate-lock-for-v4l2-control-handler.patch +media-i2c-alvium-move-v4l2_cid_gain-to-v4l2_cid_analog_gain.patch +media-imx-pxp-fix-err_ptr-dereference-in-pxp_probe.patch +jbd2-make-jbd2_journal_get_max_txn_bufs-internal.patch +jbd2-precompute-number-of-transaction-descriptor-blocks.patch +jbd2-avoid-infinite-transaction-commit-loop.patch +media-uvcvideo-fix-integer-overflow-calculating-timestamp.patch diff --git a/queue-6.10/task_work-introduce-task_work_cancel-again.patch b/queue-6.10/task_work-introduce-task_work_cancel-again.patch new file mode 100644 index 00000000000..e8510f13346 --- /dev/null +++ b/queue-6.10/task_work-introduce-task_work_cancel-again.patch @@ -0,0 +1,66 @@ +From f409530e4db9dd11b88cb7703c97c8f326ff6566 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Fri, 21 Jun 2024 11:15:59 +0200 +Subject: task_work: Introduce task_work_cancel() again + +From: Frederic Weisbecker + +commit f409530e4db9dd11b88cb7703c97c8f326ff6566 upstream. + +Re-introduce task_work_cancel(), this time to cancel an actual callback +and not *any* callback pointing to a given function. This is going to be +needed for perf events event freeing. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240621091601.18227-3-frederic@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/task_work.h | 1 + + kernel/task_work.c | 24 ++++++++++++++++++++++++ + 2 files changed, 25 insertions(+) + +--- a/include/linux/task_work.h ++++ b/include/linux/task_work.h +@@ -31,6 +31,7 @@ int task_work_add(struct task_struct *ta + struct callback_head *task_work_cancel_match(struct task_struct *task, + bool (*match)(struct callback_head *, void *data), void *data); + struct callback_head *task_work_cancel_func(struct task_struct *, task_work_func_t); ++bool task_work_cancel(struct task_struct *task, struct callback_head *cb); + void task_work_run(void); + + static inline void exit_task_work(struct task_struct *task) +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -136,6 +136,30 @@ task_work_cancel_func(struct task_struct + return task_work_cancel_match(task, task_work_func_match, func); + } + ++static bool task_work_match(struct callback_head *cb, void *data) ++{ ++ return cb == data; ++} ++ ++/** ++ * task_work_cancel - cancel a pending work added by task_work_add() ++ * @task: the task which should execute the work ++ * @cb: the callback to remove if queued ++ * ++ * Remove a callback from a task's queue if queued. ++ * ++ * RETURNS: ++ * True if the callback was queued and got cancelled, false otherwise. ++ */ ++bool task_work_cancel(struct task_struct *task, struct callback_head *cb) ++{ ++ struct callback_head *ret; ++ ++ ret = task_work_cancel_match(task, task_work_match, cb); ++ ++ return ret == cb; ++} ++ + /** + * task_work_run - execute the works added by task_work_add() + * diff --git a/queue-6.10/task_work-s-task_work_cancel-task_work_cancel_func.patch b/queue-6.10/task_work-s-task_work_cancel-task_work_cancel_func.patch new file mode 100644 index 00000000000..e3718f74c23 --- /dev/null +++ b/queue-6.10/task_work-s-task_work_cancel-task_work_cancel_func.patch @@ -0,0 +1,92 @@ +From 68cbd415dd4b9c5b9df69f0f091879e56bf5907a Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Fri, 21 Jun 2024 11:15:58 +0200 +Subject: task_work: s/task_work_cancel()/task_work_cancel_func()/ + +From: Frederic Weisbecker + +commit 68cbd415dd4b9c5b9df69f0f091879e56bf5907a upstream. + +A proper task_work_cancel() API that actually cancels a callback and not +*any* callback pointing to a given function is going to be needed for +perf events event freeing. Do the appropriate rename to prepare for +that. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240621091601.18227-2-frederic@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/task_work.h | 2 +- + kernel/irq/manage.c | 2 +- + kernel/task_work.c | 10 +++++----- + security/keys/keyctl.c | 2 +- + 4 files changed, 8 insertions(+), 8 deletions(-) + +--- a/include/linux/task_work.h ++++ b/include/linux/task_work.h +@@ -30,7 +30,7 @@ int task_work_add(struct task_struct *ta + + struct callback_head *task_work_cancel_match(struct task_struct *task, + bool (*match)(struct callback_head *, void *data), void *data); +-struct callback_head *task_work_cancel(struct task_struct *, task_work_func_t); ++struct callback_head *task_work_cancel_func(struct task_struct *, task_work_func_t); + void task_work_run(void); + + static inline void exit_task_work(struct task_struct *task) +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -1337,7 +1337,7 @@ static int irq_thread(void *data) + * synchronize_hardirq(). So neither IRQTF_RUNTHREAD nor the + * oneshot mask bit can be set. + */ +- task_work_cancel(current, irq_thread_dtor); ++ task_work_cancel_func(current, irq_thread_dtor); + return 0; + } + +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -120,9 +120,9 @@ static bool task_work_func_match(struct + } + + /** +- * task_work_cancel - cancel a pending work added by task_work_add() +- * @task: the task which should execute the work +- * @func: identifies the work to remove ++ * task_work_cancel_func - cancel a pending work matching a function added by task_work_add() ++ * @task: the task which should execute the func's work ++ * @func: identifies the func to match with a work to remove + * + * Find the last queued pending work with ->func == @func and remove + * it from queue. +@@ -131,7 +131,7 @@ static bool task_work_func_match(struct + * The found work or NULL if not found. + */ + struct callback_head * +-task_work_cancel(struct task_struct *task, task_work_func_t func) ++task_work_cancel_func(struct task_struct *task, task_work_func_t func) + { + return task_work_cancel_match(task, task_work_func_match, func); + } +@@ -168,7 +168,7 @@ void task_work_run(void) + if (!work) + break; + /* +- * Synchronize with task_work_cancel(). It can not remove ++ * Synchronize with task_work_cancel_match(). It can not remove + * the first entry == work, cmpxchg(task_works) must fail. + * But it can remove another entry from the ->next list. + */ +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -1694,7 +1694,7 @@ long keyctl_session_to_parent(void) + goto unlock; + + /* cancel an already pending keyring replacement */ +- oldwork = task_work_cancel(parent, key_change_session_keyring); ++ oldwork = task_work_cancel_func(parent, key_change_session_keyring); + + /* the replacement session keyring is applied just prior to userspace + * restarting */ diff --git a/queue-6.10/trace-pid_list-change-gfp-flags-in-pid_list_fill_irq.patch b/queue-6.10/trace-pid_list-change-gfp-flags-in-pid_list_fill_irq.patch new file mode 100644 index 00000000000..50d3774f7d7 --- /dev/null +++ b/queue-6.10/trace-pid_list-change-gfp-flags-in-pid_list_fill_irq.patch @@ -0,0 +1,50 @@ +From 7dc836187f7c6f70a82b4521503e9f9f96194581 Mon Sep 17 00:00:00 2001 +From: "levi.yun" +Date: Thu, 4 Jul 2024 16:02:26 +0100 +Subject: trace/pid_list: Change gfp flags in pid_list_fill_irq() + +From: levi.yun + +commit 7dc836187f7c6f70a82b4521503e9f9f96194581 upstream. + +pid_list_fill_irq() runs via irq_work. +When CONFIG_PREEMPT_RT is disabled, it would run in irq_context. +so it shouldn't sleep while memory allocation. + +Change gfp flags from GFP_KERNEL to GFP_NOWAIT to prevent sleep in +irq_work. + +This change wouldn't impact functionality in practice because the worst-size +is 2K. + +Cc: stable@goodmis.org +Fixes: 8d6e90983ade2 ("tracing: Create a sparse bitmask for pid filtering") +Link: https://lore.kernel.org/20240704150226.1359936-1-yeoreum.yun@arm.com +Acked-by: Masami Hiramatsu (Google) +Signed-off-by: levi.yun +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/pid_list.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/trace/pid_list.c ++++ b/kernel/trace/pid_list.c +@@ -354,7 +354,7 @@ static void pid_list_refill_irq(struct i + while (upper_count-- > 0) { + union upper_chunk *chunk; + +- chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); ++ chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + if (!chunk) + break; + *upper_next = chunk; +@@ -365,7 +365,7 @@ static void pid_list_refill_irq(struct i + while (lower_count-- > 0) { + union lower_chunk *chunk; + +- chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); ++ chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + if (!chunk) + break; + *lower_next = chunk; diff --git a/queue-6.10/udf-avoid-using-corrupted-block-bitmap-buffer.patch b/queue-6.10/udf-avoid-using-corrupted-block-bitmap-buffer.patch new file mode 100644 index 00000000000..d9780dff6fe --- /dev/null +++ b/queue-6.10/udf-avoid-using-corrupted-block-bitmap-buffer.patch @@ -0,0 +1,73 @@ +From a90d4471146de21745980cba51ce88e7926bcc4f Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 17 Jun 2024 17:41:52 +0200 +Subject: udf: Avoid using corrupted block bitmap buffer + +From: Jan Kara + +commit a90d4471146de21745980cba51ce88e7926bcc4f upstream. + +When the filesystem block bitmap is corrupted, we detect the corruption +while loading the bitmap and fail the allocation with error. However the +next allocation from the same bitmap will notice the bitmap buffer is +already loaded and tries to allocate from the bitmap with mixed results +(depending on the exact nature of the bitmap corruption). Fix the +problem by using BH_verified bit to indicate whether the bitmap is valid +or not. + +Reported-by: syzbot+5f682cd029581f9edfd1@syzkaller.appspotmail.com +CC: stable@vger.kernel.org +Link: https://patch.msgid.link/20240617154201.29512-2-jack@suse.cz +Fixes: 1e0d4adf17e7 ("udf: Check consistency of Space Bitmap Descriptor") +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + fs/udf/balloc.c | 15 +++++++++++++-- + fs/udf/super.c | 3 ++- + 2 files changed, 15 insertions(+), 3 deletions(-) + +--- a/fs/udf/balloc.c ++++ b/fs/udf/balloc.c +@@ -64,8 +64,12 @@ static int read_block_bitmap(struct supe + } + + for (i = 0; i < count; i++) +- if (udf_test_bit(i + off, bh->b_data)) ++ if (udf_test_bit(i + off, bh->b_data)) { ++ bitmap->s_block_bitmap[bitmap_nr] = ++ ERR_PTR(-EFSCORRUPTED); ++ brelse(bh); + return -EFSCORRUPTED; ++ } + return 0; + } + +@@ -81,8 +85,15 @@ static int __load_block_bitmap(struct su + block_group, nr_groups); + } + +- if (bitmap->s_block_bitmap[block_group]) ++ if (bitmap->s_block_bitmap[block_group]) { ++ /* ++ * The bitmap failed verification in the past. No point in ++ * trying again. ++ */ ++ if (IS_ERR(bitmap->s_block_bitmap[block_group])) ++ return PTR_ERR(bitmap->s_block_bitmap[block_group]); + return block_group; ++ } + + retval = read_block_bitmap(sb, bitmap, block_group, block_group); + if (retval < 0) +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -336,7 +336,8 @@ static void udf_sb_free_bitmap(struct ud + int nr_groups = bitmap->s_nr_groups; + + for (i = 0; i < nr_groups; i++) +- brelse(bitmap->s_block_bitmap[i]); ++ if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i])) ++ brelse(bitmap->s_block_bitmap[i]); + + kvfree(bitmap); + } diff --git a/queue-6.10/wifi-mwifiex-fix-interface-type-change.patch b/queue-6.10/wifi-mwifiex-fix-interface-type-change.patch new file mode 100644 index 00000000000..f8b00767bf2 --- /dev/null +++ b/queue-6.10/wifi-mwifiex-fix-interface-type-change.patch @@ -0,0 +1,40 @@ +From a17b9f590f6ec2b9f1b12b1db3bf1d181de6b272 Mon Sep 17 00:00:00 2001 +From: Rafael Beims +Date: Fri, 10 May 2024 13:04:58 +0200 +Subject: wifi: mwifiex: Fix interface type change + +From: Rafael Beims + +commit a17b9f590f6ec2b9f1b12b1db3bf1d181de6b272 upstream. + +When changing the interface type we also need to update the bss_num, the +driver private data is searched based on a unique (bss_type, bss_num) +tuple, therefore every time bss_type changes, bss_num must also change. + +This fixes for example an issue in which, after the mode changed, a +wireless scan on the changed interface would not finish, leading to +repeated -EBUSY messages to userspace when other scan requests were +sent. + +Fixes: c606008b7062 ("mwifiex: Properly initialize private structure on interface type changes") +Cc: stable@vger.kernel.org +Signed-off-by: Rafael Beims +Signed-off-by: Francesco Dolcini +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240510110458.15475-1-francesco@dolcini.it +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/marvell/mwifiex/cfg80211.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c +@@ -926,6 +926,8 @@ mwifiex_init_new_priv_params(struct mwif + return -EOPNOTSUPP; + } + ++ priv->bss_num = mwifiex_get_unused_bss_num(adapter, priv->bss_type); ++ + spin_lock_irqsave(&adapter->main_proc_lock, flags); + adapter->main_locked = false; + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); diff --git a/queue-6.10/wifi-rtw88-usb-fix-disconnection-after-beacon-loss.patch b/queue-6.10/wifi-rtw88-usb-fix-disconnection-after-beacon-loss.patch new file mode 100644 index 00000000000..0defa4839e9 --- /dev/null +++ b/queue-6.10/wifi-rtw88-usb-fix-disconnection-after-beacon-loss.patch @@ -0,0 +1,62 @@ +From 28818b4d871bc93cc4f5c7c7d7c526a6a096c09c Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Mon, 29 Apr 2024 20:57:52 +0300 +Subject: wifi: rtw88: usb: Fix disconnection after beacon loss + +From: Bitterblue Smith + +commit 28818b4d871bc93cc4f5c7c7d7c526a6a096c09c upstream. + +When there is beacon loss, for example due to unrelated Bluetooth +devices transmitting music nearby, the wifi connection dies soon +after the first beacon loss message: + +Apr 28 20:47:14 ideapad2 wpa_supplicant[1161]: wlp3s0f3u4: + CTRL-EVENT-BEACON-LOSS +Apr 28 20:47:15 ideapad2 wpa_supplicant[1161]: wlp3s0f3u4: + CTRL-EVENT-DISCONNECTED bssid=... reason=4 locally_generated=1 + +Apr 28 20:47:24 ideapad2 wpa_supplicant[1161]: wlp3s0f3u4: + CTRL-EVENT-BEACON-LOSS +Apr 28 20:47:25 ideapad2 wpa_supplicant[1161]: wlp3s0f3u4: + CTRL-EVENT-DISCONNECTED bssid=... reason=4 locally_generated=1 + +Apr 28 20:47:34 ideapad2 wpa_supplicant[1161]: wlp3s0f3u4: + CTRL-EVENT-BEACON-LOSS +Apr 28 20:47:35 ideapad2 wpa_supplicant[1161]: wlp3s0f3u4: + CTRL-EVENT-DISCONNECTED bssid=... reason=4 locally_generated=1 + +When the beacon loss happens, mac80211 makes rtw88 transmit a QOS +NULL frame and asks to confirm the ACK status. Even though rtw88 +confirms to mac80211 that the QOS NULL was transmitted successfully, +the connection still dies. This is because rtw88 is handing the QOS +NULL back to mac80211 with skb->data pointing to the headroom (the +TX descriptor) instead of ieee80211_hdr. + +Fix the disconnection by moving skb->data to the correct position +before ieee80211_tx_status_irqsafe(). + +The problem was observed with RTL8811AU (TP-Link Archer T2U Nano) +and the potential future rtw88_8821au driver. Also tested with +RTL8811CU (Tenda U9). + +Cc: stable@vger.kernel.org +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://msgid.link/ecbf0601-810d-4609-b8fc-8b0e38d2948d@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw88/usb.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -273,6 +273,8 @@ static void rtw_usb_write_port_tx_comple + info = IEEE80211_SKB_CB(skb); + tx_data = rtw_usb_get_tx_data(skb); + ++ skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); ++ + /* enqueue to wait for tx report */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); diff --git a/queue-6.10/wifi-rtw88-usb-further-limit-the-tx-aggregation.patch b/queue-6.10/wifi-rtw88-usb-further-limit-the-tx-aggregation.patch new file mode 100644 index 00000000000..eea63c98d63 --- /dev/null +++ b/queue-6.10/wifi-rtw88-usb-further-limit-the-tx-aggregation.patch @@ -0,0 +1,151 @@ +From d7dd13ea54af8496aca2762a758d817d6813e81c Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sun, 16 Jun 2024 22:27:34 +0300 +Subject: wifi: rtw88: usb: Further limit the TX aggregation + +From: Bitterblue Smith + +commit d7dd13ea54af8496aca2762a758d817d6813e81c upstream. + +Currently the number of frames sent to the chip in a single USB Request +Block is limited only by the size of the TX buffer, which is 20 KiB. +Testing reveals that as many as 13 frames get aggregated. This is more +than what any of the chips would like to receive. RTL8822CU, RTL8822BU, +and RTL8821CU want at most 3 frames, and RTL8723DU wants only 1 frame +per URB. + +RTL8723DU in particular reliably malfunctions during a speed test if it +receives more than 1 frame per URB. All traffic seems to stop. Pinging +the AP no longer works. + +Fix this problem by limiting the number of frames sent to the chip in a +single URB according to what each chip likes. + +Also configure RTL8822CU, RTL8822BU, and RTL8821CU to expect 3 frames +per URB. + +RTL8703B may or may not be found in USB devices. Declare that it wants +only 1 frame per URB, just in case. + +Tested with RTL8723DU and RTL8811CU. + +Cc: stable@vger.kernel.org +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/cb46ea35-7e59-4742-9c1f-01ceeaad36fb@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw88/mac.c | 9 +++++++++ + drivers/net/wireless/realtek/rtw88/main.h | 2 ++ + drivers/net/wireless/realtek/rtw88/reg.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/usb.c | 4 +++- + 9 files changed, 20 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -1201,6 +1201,15 @@ static int __priority_queue_cfg(struct r + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); + rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); ++ ++ if (rtwdev->hci.type == RTW_HCI_TYPE_USB) { ++ rtw_write8_mask(rtwdev, REG_AUTO_LLT_V1, BIT_MASK_BLK_DESC_NUM, ++ chip->usb_tx_agg_desc_num); ++ ++ rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, chip->usb_tx_agg_desc_num); ++ rtw_write8_set(rtwdev, REG_TXDMA_OFFSET_CHK + 1, BIT(1)); ++ } ++ + rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1197,6 +1197,8 @@ struct rtw_chip_info { + u16 fw_fifo_addr[RTW_FW_FIFO_MAX]; + const struct rtw_fwcd_segs *fwcd_segs; + ++ u8 usb_tx_agg_desc_num; ++ + u8 default_1ss_tx_path; + + bool path_div_supported; +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -270,6 +270,7 @@ + #define BIT_MASK_BCN_HEAD_1_V1 0xfff + #define REG_AUTO_LLT_V1 0x0208 + #define BIT_AUTO_INIT_LLT_V1 BIT(0) ++#define BIT_MASK_BLK_DESC_NUM GENMASK(7, 4) + #define REG_DWBCN0_CTRL 0x0208 + #define BIT_BCN_VALID BIT(16) + #define REG_TXDMA_OFFSET_CHK 0x020C +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -2013,6 +2013,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .tx_stbc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2171,6 +2171,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .band = RTW_BAND_2G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, ++ .usb_tx_agg_desc_num = 1, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -2008,6 +2008,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, ++ .usb_tx_agg_desc_num = 3, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2548,6 +2548,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, ++ .usb_tx_agg_desc_num = 3, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5366,6 +5366,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, ++ .usb_tx_agg_desc_num = 3, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -379,7 +379,9 @@ static bool rtw_usb_tx_agg_skb(struct rt + + skb_iter = skb_peek(list); + +- if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ) ++ if (skb_iter && ++ skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ && ++ agg_num < rtwdev->chip->usb_tx_agg_desc_num) + __skb_unlink(skb_iter, list); + else + skb_iter = NULL; diff --git a/queue-6.10/wifi-rtw89-fix-hw-scan-not-aborting-properly.patch b/queue-6.10/wifi-rtw89-fix-hw-scan-not-aborting-properly.patch new file mode 100644 index 00000000000..a67ccc21674 --- /dev/null +++ b/queue-6.10/wifi-rtw89-fix-hw-scan-not-aborting-properly.patch @@ -0,0 +1,75 @@ +From 669b692247d4516e252c898c0e7366a09d84d1be Mon Sep 17 00:00:00 2001 +From: Po-Hao Huang +Date: Fri, 17 May 2024 09:33:50 +0800 +Subject: wifi: rtw89: fix HW scan not aborting properly + +From: Po-Hao Huang + +commit 669b692247d4516e252c898c0e7366a09d84d1be upstream. + +There is a length limit on the commands we send to firmware, so +dividing to two commands is sometimes required when scanning. +When aborting scan, we should not send second scan command to +firmware after the first one is finished. This could cause some +unexpected errors when we cannot receive firmware events +(e.g. in suspend). + +Another case is scan happens before suspending, ieee80211_do_stop() is +called to abort scan and driver indicate scan completion by +ieee80211_scan_completed(), which queues event to scan work. But scan work +might be late to execute after ieee80211_do_stop(). To correct this, driver +indicates ieee80211_scan_completed() before returning, so that +ieee80211_do_stop() can flush scan work properly. + +Fixes: bcbefbd032df ("wifi: rtw89: add wait/completion for abort scan") +Cc: stable@vger.kernel.org +Co-developed-by: Chih-Kang Chang +Signed-off-by: Chih-Kang Chang +Signed-off-by: Po-Hao Huang +Signed-off-by: Ping-Ke Shih +Link: https://msgid.link/20240517013350.11278-1-pkshih@realtek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw89/fw.c | 9 ++++++++- + drivers/net/wireless/realtek/rtw89/mac.c | 5 ++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -6245,7 +6245,14 @@ void rtw89_hw_scan_abort(struct rtw89_de + + ret = rtw89_hw_scan_offload(rtwdev, vif, false); + if (ret) +- rtw89_hw_scan_complete(rtwdev, vif, true); ++ rtw89_warn(rtwdev, "rtw89_hw_scan_offload failed ret %d\n", ret); ++ ++ /* Indicate ieee80211_scan_completed() before returning, which is safe ++ * because scan abort command always waits for completion of ++ * RTW89_SCAN_END_SCAN_NOTIFY, so that ieee80211_stop() can flush scan ++ * work properly. ++ */ ++ rtw89_hw_scan_complete(rtwdev, vif, true); + } + + static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4757,6 +4757,9 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_ + } + return; + case RTW89_SCAN_END_SCAN_NOTIFY: ++ if (rtwdev->scan_info.abort) ++ return; ++ + if (rtwvif && rtwvif->scan_req && + last_chan < rtwvif->scan_req->n_channels) { + ret = rtw89_hw_scan_offload(rtwdev, vif, true); +@@ -4765,7 +4768,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_ + rtw89_warn(rtwdev, "HW scan failed: %d\n", ret); + } + } else { +- rtw89_hw_scan_complete(rtwdev, vif, rtwdev->scan_info.abort); ++ rtw89_hw_scan_complete(rtwdev, vif, false); + } + break; + case RTW89_SCAN_ENTER_OP_NOTIFY: