From: Sasha Levin Date: Wed, 21 Aug 2024 13:31:14 +0000 (-0400) Subject: Fixes for 6.6 X-Git-Tag: v6.1.107~103 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=368c175cea497c52dd391cf16bac04282fabaa3b;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/accel-habanalabs-fix-debugfs-files-permissions.patch b/queue-6.6/accel-habanalabs-fix-debugfs-files-permissions.patch new file mode 100644 index 00000000000..96003e95cbd --- /dev/null +++ b/queue-6.6/accel-habanalabs-fix-debugfs-files-permissions.patch @@ -0,0 +1,85 @@ +From 1c5cbfdc012dc576d1cc3b05e11e5f2f251225ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jan 2024 17:54:36 +0200 +Subject: accel/habanalabs: fix debugfs files permissions + +From: Avri Kehat + +[ Upstream commit 0b105a2a7225f2736bd07aca0538cd67f09bfa20 ] + +debugfs files are created with permissions that don't align +with the access requirements. + +Signed-off-by: Avri Kehat +Reviewed-by: Oded Gabbay +Reviewed-by: Carl Vanderlip +Signed-off-by: Oded Gabbay +Signed-off-by: Sasha Levin +--- + drivers/accel/habanalabs/common/debugfs.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/accel/habanalabs/common/debugfs.c b/drivers/accel/habanalabs/common/debugfs.c +index 9e84a47a21dcf..7d733e4d50611 100644 +--- a/drivers/accel/habanalabs/common/debugfs.c ++++ b/drivers/accel/habanalabs/common/debugfs.c +@@ -1645,19 +1645,19 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent + &hl_data64b_fops); + + debugfs_create_file("set_power_state", +- 0200, ++ 0644, + root, + dev_entry, + &hl_power_fops); + + debugfs_create_file("device", +- 0200, ++ 0644, + root, + dev_entry, + &hl_device_fops); + + debugfs_create_file("clk_gate", +- 0200, ++ 0644, + root, + dev_entry, + &hl_clk_gate_fops); +@@ -1669,13 +1669,13 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent + &hl_stop_on_err_fops); + + debugfs_create_file("dump_security_violations", +- 0644, ++ 0400, + root, + dev_entry, + &hl_security_violations_fops); + + debugfs_create_file("dump_razwi_events", +- 0644, ++ 0400, + root, + dev_entry, + &hl_razwi_check_fops); +@@ -1708,7 +1708,7 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent + &hdev->reset_info.skip_reset_on_timeout); + + debugfs_create_file("state_dump", +- 0600, ++ 0644, + root, + dev_entry, + &hl_state_dump_fops); +@@ -1726,7 +1726,7 @@ static void add_files_to_device(struct hl_device *hdev, struct hl_dbg_device_ent + + for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { + debugfs_create_file(hl_debugfs_list[i].name, +- 0444, ++ 0644, + root, + entry, + &hl_debugfs_fops); +-- +2.43.0 + diff --git a/queue-6.6/afs-fix-__afs_break_callback-afs_drop_open_mmap-race.patch b/queue-6.6/afs-fix-__afs_break_callback-afs_drop_open_mmap-race.patch new file mode 100644 index 00000000000..3a74babb7e6 --- /dev/null +++ b/queue-6.6/afs-fix-__afs_break_callback-afs_drop_open_mmap-race.patch @@ -0,0 +1,57 @@ +From 7de1d889e41c98b30bb38fd49bb7b85cc3d4714b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 20:24:34 -0400 +Subject: afs: fix __afs_break_callback() / afs_drop_open_mmap() race + +From: Al Viro + +[ Upstream commit 275655d3207b9e65d1561bf21c06a622d9ec1d43 ] + +In __afs_break_callback() we might check ->cb_nr_mmap and if it's non-zero +do queue_work(&vnode->cb_work). In afs_drop_open_mmap() we decrement +->cb_nr_mmap and do flush_work(&vnode->cb_work) if it reaches zero. + +The trouble is, there's nothing to prevent __afs_break_callback() from +seeing ->cb_nr_mmap before the decrement and do queue_work() after both +the decrement and flush_work(). If that happens, we might be in trouble - +vnode might get freed before the queued work runs. + +__afs_break_callback() is always done under ->cb_lock, so let's make +sure that ->cb_nr_mmap can change from non-zero to zero while holding +->cb_lock (the spinlock component of it - it's a seqlock and we don't +need to mess with the counter). + +Acked-by: Christian Brauner +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/afs/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/fs/afs/file.c b/fs/afs/file.c +index d37dd201752ba..0012ea300eb53 100644 +--- a/fs/afs/file.c ++++ b/fs/afs/file.c +@@ -529,13 +529,17 @@ static void afs_add_open_mmap(struct afs_vnode *vnode) + + static void afs_drop_open_mmap(struct afs_vnode *vnode) + { +- if (!atomic_dec_and_test(&vnode->cb_nr_mmap)) ++ if (atomic_add_unless(&vnode->cb_nr_mmap, -1, 1)) + return; + + down_write(&vnode->volume->cell->fs_open_mmaps_lock); + +- if (atomic_read(&vnode->cb_nr_mmap) == 0) ++ read_seqlock_excl(&vnode->cb_lock); ++ // the only place where ->cb_nr_mmap may hit 0 ++ // see __afs_break_callback() for the other side... ++ if (atomic_dec_and_test(&vnode->cb_nr_mmap)) + list_del_init(&vnode->cb_mmap_link); ++ read_sequnlock_excl(&vnode->cb_lock); + + up_write(&vnode->volume->cell->fs_open_mmaps_lock); + flush_work(&vnode->cb_work); +-- +2.43.0 + diff --git a/queue-6.6/asoc-sof-ipc4-check-return-value-of-snd_sof_ipc_msg_.patch b/queue-6.6/asoc-sof-ipc4-check-return-value-of-snd_sof_ipc_msg_.patch new file mode 100644 index 00000000000..a2675586c68 --- /dev/null +++ b/queue-6.6/asoc-sof-ipc4-check-return-value-of-snd_sof_ipc_msg_.patch @@ -0,0 +1,48 @@ +From 481182e47186a5ecd04c717794bfb956d275319b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 14:20:21 +0200 +Subject: ASoC: SOF: ipc4: check return value of snd_sof_ipc_msg_data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bard Liao + +[ Upstream commit 2bd512626f8ea3957c981cadd2ebf75feff737dd ] + +snd_sof_ipc_msg_data could return error. + +Signed-off-by: Bard Liao +Reviewed-by: Péter Ujfalusi +Reviewed-by: Pierre-Louis Bossart +Signed-off-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/20231129122021.679-1-peter.ujfalusi@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/ipc4.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c +index 1b09496733fb8..81d1ce4b5f0cd 100644 +--- a/sound/soc/sof/ipc4.c ++++ b/sound/soc/sof/ipc4.c +@@ -629,7 +629,14 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev) + return; + + ipc4_msg->data_size = data_size; +- snd_sof_ipc_msg_data(sdev, NULL, ipc4_msg->data_ptr, ipc4_msg->data_size); ++ err = snd_sof_ipc_msg_data(sdev, NULL, ipc4_msg->data_ptr, ipc4_msg->data_size); ++ if (err < 0) { ++ dev_err(sdev->dev, "failed to read IPC notification data: %d\n", err); ++ kfree(ipc4_msg->data_ptr); ++ ipc4_msg->data_ptr = NULL; ++ ipc4_msg->data_size = 0; ++ return; ++ } + } + + sof_ipc4_log_header(sdev->dev, "ipc rx done ", ipc4_msg, true); +-- +2.43.0 + diff --git a/queue-6.6/bluetooth-bnep-fix-out-of-bound-access.patch b/queue-6.6/bluetooth-bnep-fix-out-of-bound-access.patch new file mode 100644 index 00000000000..4ed2f22b8fd --- /dev/null +++ b/queue-6.6/bluetooth-bnep-fix-out-of-bound-access.patch @@ -0,0 +1,38 @@ +From c7b5f21d2ede888b7428bdcf496efa3910ff9e9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Feb 2024 12:11:08 -0500 +Subject: Bluetooth: bnep: Fix out-of-bound access + +From: Luiz Augusto von Dentz + +[ Upstream commit 0f0639b4d6f649338ce29c62da3ec0787fa08cd1 ] + +This fixes attempting to access past ethhdr.h_source, although it seems +intentional to copy also the contents of h_proto this triggers +out-of-bound access problems with the likes of static analyzer, so this +instead just copy ETH_ALEN and then proceed to use put_unaligned to copy +h_proto separetely. + +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/bnep/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c +index 5a6a49885ab66..a660c428e2207 100644 +--- a/net/bluetooth/bnep/core.c ++++ b/net/bluetooth/bnep/core.c +@@ -385,7 +385,8 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) + + case BNEP_COMPRESSED_DST_ONLY: + __skb_put_data(nskb, skb_mac_header(skb), ETH_ALEN); +- __skb_put_data(nskb, s->eh.h_source, ETH_ALEN + 2); ++ __skb_put_data(nskb, s->eh.h_source, ETH_ALEN); ++ put_unaligned(s->eh.h_proto, (__be16 *)__skb_put(nskb, 2)); + break; + + case BNEP_GENERAL: +-- +2.43.0 + diff --git a/queue-6.6/bluetooth-hci_conn-check-non-null-function-before-ca.patch b/queue-6.6/bluetooth-hci_conn-check-non-null-function-before-ca.patch new file mode 100644 index 00000000000..ba9759f4cff --- /dev/null +++ b/queue-6.6/bluetooth-hci_conn-check-non-null-function-before-ca.patch @@ -0,0 +1,54 @@ +From 9e528e44c547356192ae45aa492703f129b22994 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Dec 2023 09:51:26 +0800 +Subject: Bluetooth: hci_conn: Check non NULL function before calling for HFP + offload + +From: Zijun Hu + +[ Upstream commit 132d0fd0b8418094c9e269e5bc33bf5b864f4a65 ] + +For some controllers such as QCA2066, it does not need to send +HCI_Configure_Data_Path to configure non-HCI data transport path to support +HFP offload, their device drivers may set hdev->get_codec_config_data as +NULL, so Explicitly add this non NULL checking before calling the function. + +Signed-off-by: Zijun Hu +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 9c670348fac42..dc1c07c7d4ff9 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -299,6 +299,13 @@ static int configure_datapath_sync(struct hci_dev *hdev, struct bt_codec *codec) + __u8 vnd_len, *vnd_data = NULL; + struct hci_op_configure_data_path *cmd = NULL; + ++ if (!codec->data_path || !hdev->get_codec_config_data) ++ return 0; ++ ++ /* Do not take me as error */ ++ if (!hdev->get_codec_config_data) ++ return 0; ++ + err = hdev->get_codec_config_data(hdev, ESCO_LINK, codec, &vnd_len, + &vnd_data); + if (err < 0) +@@ -344,9 +351,7 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data) + + bt_dev_dbg(hdev, "hcon %p", conn); + +- /* for offload use case, codec needs to configured before opening SCO */ +- if (conn->codec.data_path) +- configure_datapath_sync(hdev, &conn->codec); ++ configure_datapath_sync(hdev, &conn->codec); + + conn->state = BT_CONNECT; + conn->out = true; +-- +2.43.0 + diff --git a/queue-6.6/btrfs-change-bug_on-to-assertion-in-tree_move_down.patch b/queue-6.6/btrfs-change-bug_on-to-assertion-in-tree_move_down.patch new file mode 100644 index 00000000000..c3c6d3f4b04 --- /dev/null +++ b/queue-6.6/btrfs-change-bug_on-to-assertion-in-tree_move_down.patch @@ -0,0 +1,35 @@ +From 0b423aba6ffb2eb95f03c251f42f9ceb48589383 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 23:06:46 +0100 +Subject: btrfs: change BUG_ON to assertion in tree_move_down() + +From: David Sterba + +[ Upstream commit 56f335e043ae73c32dbb70ba95488845dc0f1e6e ] + +There's only one caller of tree_move_down() that does not pass level 0 +so the assertion is better suited here. + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/send.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index 9da3c72eb6153..163f36eb7491a 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -7448,8 +7448,8 @@ static int tree_move_down(struct btrfs_path *path, int *level, u64 reada_min_gen + u64 reada_done = 0; + + lockdep_assert_held_read(&parent->fs_info->commit_root_sem); ++ ASSERT(*level != 0); + +- BUG_ON(*level == 0); + eb = btrfs_read_node_slot(parent, slot); + if (IS_ERR(eb)) + return PTR_ERR(eb); +-- +2.43.0 + diff --git a/queue-6.6/btrfs-change-bug_on-to-assertion-when-checking-for-d.patch b/queue-6.6/btrfs-change-bug_on-to-assertion-when-checking-for-d.patch new file mode 100644 index 00000000000..36846c79c9e --- /dev/null +++ b/queue-6.6/btrfs-change-bug_on-to-assertion-when-checking-for-d.patch @@ -0,0 +1,36 @@ +From 614415c390f34a8280b0c9cd0b9b3736255be1d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 20 Jan 2024 02:26:32 +0100 +Subject: btrfs: change BUG_ON to assertion when checking for delayed_node root + +From: David Sterba + +[ Upstream commit be73f4448b607e6b7ce41cd8ef2214fdf6e7986f ] + +The pointer to root is initialized in btrfs_init_delayed_node(), no need +to check for it again. Change the BUG_ON to assertion. + +Reviewed-by: Josef Bacik +Reviewed-by: Anand Jain +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/delayed-inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 12ff91d6f570f..32c5f5a8a0e93 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -973,7 +973,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) + + if (delayed_node && + test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { +- BUG_ON(!delayed_node->root); ++ ASSERT(delayed_node->root); + clear_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags); + delayed_node->count--; + +-- +2.43.0 + diff --git a/queue-6.6/btrfs-defrag-change-bug_on-to-assertion-in-btrfs_def.patch b/queue-6.6/btrfs-defrag-change-bug_on-to-assertion-in-btrfs_def.patch new file mode 100644 index 00000000000..f1b1765315e --- /dev/null +++ b/queue-6.6/btrfs-defrag-change-bug_on-to-assertion-in-btrfs_def.patch @@ -0,0 +1,37 @@ +From aaad6fc81559acdb7845ba6eb415961987ad06e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Jan 2024 20:15:41 +0100 +Subject: btrfs: defrag: change BUG_ON to assertion in btrfs_defrag_leaves() + +From: David Sterba + +[ Upstream commit 51d4be540054be32d7ce28b63ea9b84ac6ff1db2 ] + +The BUG_ON verifies a condition that should be guaranteed by the correct +use of the path search (with keep_locks and lowest_level set), an +assertion is the suitable check. + +Reviewed-by: Josef Bacik +Reviewed-by: Anand Jain +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/defrag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c +index a2e614cf3c19c..e1475dfdf7a8b 100644 +--- a/fs/btrfs/defrag.c ++++ b/fs/btrfs/defrag.c +@@ -416,7 +416,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, + * keep_locks set and lowest_level is 1, regardless of the value of + * path->slots[1]. + */ +- BUG_ON(path->locks[1] == 0); ++ ASSERT(path->locks[1] != 0); + ret = btrfs_realloc_node(trans, root, + path->nodes[1], 0, + &last_ret, +-- +2.43.0 + diff --git a/queue-6.6/btrfs-delayed-inode-drop-pointless-bug_on-in-__btrfs.patch b/queue-6.6/btrfs-delayed-inode-drop-pointless-bug_on-in-__btrfs.patch new file mode 100644 index 00000000000..a32e599a447 --- /dev/null +++ b/queue-6.6/btrfs-delayed-inode-drop-pointless-bug_on-in-__btrfs.patch @@ -0,0 +1,38 @@ +From a56643a4af1654e81bb7a22d120fddce9e0516d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 20 Jan 2024 02:22:37 +0100 +Subject: btrfs: delayed-inode: drop pointless BUG_ON in + __btrfs_remove_delayed_item() + +From: David Sterba + +[ Upstream commit 778e618b8bfedcc39354373c1b072c5fe044fa7b ] + +There's a BUG_ON checking for a valid pointer of fs_info::delayed_root +but it is valid since init_mount_fs_info() and has the same lifetime as +fs_info. + +Reviewed-by: Josef Bacik +Reviewed-by: Anand Jain +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/delayed-inode.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 6d562f18d3f80..12ff91d6f570f 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -425,8 +425,6 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) + + delayed_root = delayed_node->root->fs_info->delayed_root; + +- BUG_ON(!delayed_root); +- + if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM) + root = &delayed_node->ins_root; + else +-- +2.43.0 + diff --git a/queue-6.6/btrfs-delete-pointless-bug_on-check-on-quota-root-in.patch b/queue-6.6/btrfs-delete-pointless-bug_on-check-on-quota-root-in.patch new file mode 100644 index 00000000000..161bdbfd85f --- /dev/null +++ b/queue-6.6/btrfs-delete-pointless-bug_on-check-on-quota-root-in.patch @@ -0,0 +1,40 @@ +From f9fabcd656af1a5aa5fdc51a32364bcc8806c5dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 23:20:53 +0100 +Subject: btrfs: delete pointless BUG_ON check on quota root in + btrfs_qgroup_account_extent() + +From: David Sterba + +[ Upstream commit f40a3ea94881f668084f68f6b9931486b1606db0 ] + +The BUG_ON is deep in the qgroup code where we can expect that it +exists. A NULL pointer would cause a crash. + +It was added long ago in 550d7a2ed5db35 ("btrfs: qgroup: Add new qgroup +calculation function btrfs_qgroup_account_extents()."). It maybe made +sense back then as the quota enable/disable state machine was not that +robust as it is nowadays, so we can just delete it. + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/qgroup.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 223dfbf009938..efe84be65a440 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -2725,8 +2725,6 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr, + if (nr_old_roots == 0 && nr_new_roots == 0) + goto out_free; + +- BUG_ON(!fs_info->quota_root); +- + trace_btrfs_qgroup_account_extent(fs_info, trans->transid, bytenr, + num_bytes, nr_old_roots, nr_new_roots); + +-- +2.43.0 + diff --git a/queue-6.6/btrfs-handle-invalid-root-reference-found-in-may_des.patch b/queue-6.6/btrfs-handle-invalid-root-reference-found-in-may_des.patch new file mode 100644 index 00000000000..a6e129a897f --- /dev/null +++ b/queue-6.6/btrfs-handle-invalid-root-reference-found-in-may_des.patch @@ -0,0 +1,42 @@ +From f05847ff394091fd8f7cd6a68b117335569ddf1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Jan 2024 22:58:01 +0100 +Subject: btrfs: handle invalid root reference found in may_destroy_subvol() + +From: David Sterba + +[ Upstream commit 6fbc6f4ac1f4907da4fc674251527e7dc79ffbf6 ] + +The may_destroy_subvol() looks up a root by a key, allowing to do an +inexact search when key->offset is -1. It's never expected to find such +item, as it would break the allowed range of a root id. + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index dff47ba858a0a..7071a58e5b9d4 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -4374,7 +4374,14 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) + ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0); + if (ret < 0) + goto out; +- BUG_ON(ret == 0); ++ if (ret == 0) { ++ /* ++ * Key with offset -1 found, there would have to exist a root ++ * with such id, but this is out of valid range. ++ */ ++ ret = -EUCLEAN; ++ goto out; ++ } + + ret = 0; + if (path->slots[0] > 0) { +-- +2.43.0 + diff --git a/queue-6.6/btrfs-push-errors-up-from-add_async_extent.patch b/queue-6.6/btrfs-push-errors-up-from-add_async_extent.patch new file mode 100644 index 00000000000..ac69348f3a0 --- /dev/null +++ b/queue-6.6/btrfs-push-errors-up-from-add_async_extent.patch @@ -0,0 +1,60 @@ +From fdbc8b598601f923c1ed95429fecb3e3ed5b7d32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Jan 2024 17:26:25 +0100 +Subject: btrfs: push errors up from add_async_extent() + +From: David Sterba + +[ Upstream commit dbe6cda68f0e1be269e6509c8bf3d8d89089c1c4 ] + +The memory allocation error in add_async_extent() is not handled +properly, return an error and push the BUG_ON to the caller. Handling it +there is not trivial so at least make it visible. + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 5ddee801a8303..dff47ba858a0a 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -730,7 +730,8 @@ static noinline int add_async_extent(struct async_chunk *cow, + struct async_extent *async_extent; + + async_extent = kmalloc(sizeof(*async_extent), GFP_NOFS); +- BUG_ON(!async_extent); /* -ENOMEM */ ++ if (!async_extent) ++ return -ENOMEM; + async_extent->start = start; + async_extent->ram_size = ram_size; + async_extent->compressed_size = compressed_size; +@@ -1017,8 +1018,9 @@ static void compress_file_range(struct btrfs_work *work) + * The async work queues will take care of doing actual allocation on + * disk for these compressed pages, and will submit the bios. + */ +- add_async_extent(async_chunk, start, total_in, total_compressed, pages, +- nr_pages, compress_type); ++ ret = add_async_extent(async_chunk, start, total_in, total_compressed, pages, ++ nr_pages, compress_type); ++ BUG_ON(ret); + if (start + total_in < end) { + start += total_in; + cond_resched(); +@@ -1030,8 +1032,9 @@ static void compress_file_range(struct btrfs_work *work) + if (!btrfs_test_opt(fs_info, FORCE_COMPRESS) && !inode->prop_compress) + inode->flags |= BTRFS_INODE_NOCOMPRESS; + cleanup_and_bail_uncompressed: +- add_async_extent(async_chunk, start, end - start + 1, 0, NULL, 0, +- BTRFS_COMPRESS_NONE); ++ ret = add_async_extent(async_chunk, start, end - start + 1, 0, NULL, 0, ++ BTRFS_COMPRESS_NONE); ++ BUG_ON(ret); + free_pages: + if (pages) { + for (i = 0; i < nr_pages; i++) { +-- +2.43.0 + diff --git a/queue-6.6/btrfs-send-handle-unexpected-data-in-header-buffer-i.patch b/queue-6.6/btrfs-send-handle-unexpected-data-in-header-buffer-i.patch new file mode 100644 index 00000000000..f4119ea7eda --- /dev/null +++ b/queue-6.6/btrfs-send-handle-unexpected-data-in-header-buffer-i.patch @@ -0,0 +1,40 @@ +From a7356c25b5ac962e1f23398e0d7012dbe6e5f7c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 22:47:13 +0100 +Subject: btrfs: send: handle unexpected data in header buffer in begin_cmd() + +From: David Sterba + +[ Upstream commit e80e3f732cf53c64b0d811e1581470d67f6c3228 ] + +Change BUG_ON to a proper error handling in the unlikely case of seeing +data when the command is started. This is supposed to be reset when the +command is finished (send_cmd, send_encoded_extent). + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/send.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index 651f0865bb0df..b153f6a96fc8c 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -777,7 +777,12 @@ static int begin_cmd(struct send_ctx *sctx, int cmd) + if (WARN_ON(!sctx->send_buf)) + return -EINVAL; + +- BUG_ON(sctx->send_size); ++ if (unlikely(sctx->send_size != 0)) { ++ btrfs_err(sctx->send_root->fs_info, ++ "send: command header buffer not empty cmd %d offset %llu", ++ cmd, sctx->send_off); ++ return -EINVAL; ++ } + + sctx->send_size += sizeof(*hdr); + hdr = (struct btrfs_cmd_header *)sctx->send_buf; +-- +2.43.0 + diff --git a/queue-6.6/btrfs-send-handle-unexpected-inode-in-header-process.patch b/queue-6.6/btrfs-send-handle-unexpected-inode-in-header-process.patch new file mode 100644 index 00000000000..732fe2a6e5b --- /dev/null +++ b/queue-6.6/btrfs-send-handle-unexpected-inode-in-header-process.patch @@ -0,0 +1,41 @@ +From 11aca56b46f527e5ac39c3d1f875bbcbfb70809d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 22:47:13 +0100 +Subject: btrfs: send: handle unexpected inode in header + process_recorded_refs() + +From: David Sterba + +[ Upstream commit 5d2288711ccc483feca73151c46ee835bda17839 ] + +Change BUG_ON to proper error handling when an unexpected inode number +is encountered. As the comment says this should never happen. + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/send.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index b153f6a96fc8c..9da3c72eb6153 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -4195,7 +4195,13 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) + * This should never happen as the root dir always has the same ref + * which is always '..' + */ +- BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID); ++ if (unlikely(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID)) { ++ btrfs_err(fs_info, ++ "send: unexpected inode %llu in process_recorded_refs()", ++ sctx->cur_ino); ++ ret = -EINVAL; ++ goto out; ++ } + + valid_path = fs_path_alloc(); + if (!valid_path) { +-- +2.43.0 + diff --git a/queue-6.6/btrfs-tests-allocate-dummy-fs_info-and-root-in-test_.patch b/queue-6.6/btrfs-tests-allocate-dummy-fs_info-and-root-in-test_.patch new file mode 100644 index 00000000000..4de847eb6ce --- /dev/null +++ b/queue-6.6/btrfs-tests-allocate-dummy-fs_info-and-root-in-test_.patch @@ -0,0 +1,94 @@ +From 273f5b5c2b8814eddb3d7a283a981b029c74a3b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Jan 2024 19:04:33 +0100 +Subject: btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() + +From: David Sterba + +[ Upstream commit b2136cc288fce2f24a92f3d656531b2d50ebec5a ] + +Allocate fs_info and root to have a valid fs_info pointer in case it's +dereferenced by a helper outside of tests, like find_lock_delalloc_range(). + +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tests/extent-io-tests.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c +index 1cc86af97dc6e..f4fd3fb7c887b 100644 +--- a/fs/btrfs/tests/extent-io-tests.c ++++ b/fs/btrfs/tests/extent-io-tests.c +@@ -11,6 +11,7 @@ + #include "btrfs-tests.h" + #include "../ctree.h" + #include "../extent_io.h" ++#include "../disk-io.h" + #include "../btrfs_inode.h" + + #define PROCESS_UNLOCK (1 << 0) +@@ -105,9 +106,11 @@ static void dump_extent_io_tree(const struct extent_io_tree *tree) + } + } + +-static int test_find_delalloc(u32 sectorsize) ++static int test_find_delalloc(u32 sectorsize, u32 nodesize) + { +- struct inode *inode; ++ struct btrfs_fs_info *fs_info; ++ struct btrfs_root *root = NULL; ++ struct inode *inode = NULL; + struct extent_io_tree *tmp; + struct page *page; + struct page *locked_page = NULL; +@@ -121,12 +124,27 @@ static int test_find_delalloc(u32 sectorsize) + + test_msg("running find delalloc tests"); + ++ fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize); ++ if (!fs_info) { ++ test_std_err(TEST_ALLOC_FS_INFO); ++ return -ENOMEM; ++ } ++ ++ root = btrfs_alloc_dummy_root(fs_info); ++ if (IS_ERR(root)) { ++ test_std_err(TEST_ALLOC_ROOT); ++ ret = PTR_ERR(root); ++ goto out; ++ } ++ + inode = btrfs_new_test_inode(); + if (!inode) { + test_std_err(TEST_ALLOC_INODE); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto out; + } + tmp = &BTRFS_I(inode)->io_tree; ++ BTRFS_I(inode)->root = root; + + /* + * Passing NULL as we don't have fs_info but tracepoints are not used +@@ -316,6 +334,8 @@ static int test_find_delalloc(u32 sectorsize) + process_page_range(inode, 0, total_dirty - 1, + PROCESS_UNLOCK | PROCESS_RELEASE); + iput(inode); ++ btrfs_free_dummy_root(root); ++ btrfs_free_dummy_fs_info(fs_info); + return ret; + } + +@@ -794,7 +814,7 @@ int btrfs_test_extent_io(u32 sectorsize, u32 nodesize) + + test_msg("running extent I/O tests"); + +- ret = test_find_delalloc(sectorsize); ++ ret = test_find_delalloc(sectorsize, nodesize); + if (ret) + goto out; + +-- +2.43.0 + diff --git a/queue-6.6/btrfs-zlib-fix-and-simplify-the-inline-extent-decomp.patch b/queue-6.6/btrfs-zlib-fix-and-simplify-the-inline-extent-decomp.patch new file mode 100644 index 00000000000..6892896d136 --- /dev/null +++ b/queue-6.6/btrfs-zlib-fix-and-simplify-the-inline-extent-decomp.patch @@ -0,0 +1,270 @@ +From 85aa48e883ddf30419d30726d9f26a2c3ba45db8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Jan 2024 19:38:44 +1030 +Subject: btrfs: zlib: fix and simplify the inline extent decompression + +From: Qu Wenruo + +[ Upstream commit 2c25716dcc25a0420c4ad49d6e6bf61e60a21434 ] + +[BUG] + +If we have a filesystem with 4k sectorsize, and an inlined compressed +extent created like this: + + item 4 key (257 INODE_ITEM 0) itemoff 15863 itemsize 160 + generation 8 transid 8 size 4096 nbytes 4096 + block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0 + sequence 1 flags 0x0(none) + item 5 key (257 INODE_REF 256) itemoff 15839 itemsize 24 + index 2 namelen 14 name: source_inlined + item 6 key (257 EXTENT_DATA 0) itemoff 15770 itemsize 69 + generation 8 type 0 (inline) + inline extent data size 48 ram_bytes 4096 compression 1 (zlib) + +Which has an inline compressed extent at file offset 0, and its +decompressed size is 4K, allowing us to reflink that 4K range to another +location (which will not be compressed). + +If we do such reflink on a subpage system, it would fail like this: + + # xfs_io -f -c "reflink $mnt/source_inlined 0 60k 4k" $mnt/dest + XFS_IOC_CLONE_RANGE: Input/output error + +[CAUSE] +In zlib_decompress(), we didn't treat @start_byte as just a page offset, +but also use it as an indicator on whether we should switch our output +buffer. + +In reality, for subpage cases, although @start_byte can be non-zero, +we should never switch input/output buffer, since the whole input/output +buffer should never exceed one sector. + +Note: The above assumption is only not true if we're going to support +multi-page sectorsize. + +Thus the current code using @start_byte as a condition to switch +input/output buffer or finish the decompression is completely incorrect. + +[FIX] +The fix involves several modifications: + +- Rename @start_byte to @dest_pgoff to properly express its meaning + +- Add an extra ASSERT() inside btrfs_decompress() to make sure the + input/output size never exceeds one sector. + +- Use Z_FINISH flag to make sure the decompression happens in one go + +- Remove the loop needed to switch input/output buffers + +- Use correct destination offset inside the destination page + +- Consider early end as an error + +After the fix, even on 64K page sized aarch64, above reflink now +works as expected: + + # xfs_io -f -c "reflink $mnt/source_inlined 0 60k 4k" $mnt/dest + linked 4096/4096 bytes at offset 61440 + +And resulted a correct file layout: + + item 9 key (258 INODE_ITEM 0) itemoff 15542 itemsize 160 + generation 10 transid 10 size 65536 nbytes 4096 + block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0 + sequence 1 flags 0x0(none) + item 10 key (258 INODE_REF 256) itemoff 15528 itemsize 14 + index 3 namelen 4 name: dest + item 11 key (258 XATTR_ITEM 3817753667) itemoff 15445 itemsize 83 + location key (0 UNKNOWN.0 0) type XATTR + transid 10 data_len 37 name_len 16 + name: security.selinux + data unconfined_u:object_r:unlabeled_t:s0 + item 12 key (258 EXTENT_DATA 61440) itemoff 15392 itemsize 53 + generation 10 type 1 (regular) + extent data disk byte 13631488 nr 4096 + extent data offset 0 nr 4096 ram 4096 + extent compression 0 (none) + +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/compression.c | 23 +++++++++---- + fs/btrfs/compression.h | 2 +- + fs/btrfs/zlib.c | 73 +++++++++++------------------------------- + 3 files changed, 36 insertions(+), 62 deletions(-) + +diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c +index a815ce9cfb518..e6acf09a1507c 100644 +--- a/fs/btrfs/compression.c ++++ b/fs/btrfs/compression.c +@@ -140,16 +140,16 @@ static int compression_decompress_bio(struct list_head *ws, + } + + static int compression_decompress(int type, struct list_head *ws, +- const u8 *data_in, struct page *dest_page, +- unsigned long start_byte, size_t srclen, size_t destlen) ++ const u8 *data_in, struct page *dest_page, ++ unsigned long dest_pgoff, size_t srclen, size_t destlen) + { + switch (type) { + case BTRFS_COMPRESS_ZLIB: return zlib_decompress(ws, data_in, dest_page, +- start_byte, srclen, destlen); ++ dest_pgoff, srclen, destlen); + case BTRFS_COMPRESS_LZO: return lzo_decompress(ws, data_in, dest_page, +- start_byte, srclen, destlen); ++ dest_pgoff, srclen, destlen); + case BTRFS_COMPRESS_ZSTD: return zstd_decompress(ws, data_in, dest_page, +- start_byte, srclen, destlen); ++ dest_pgoff, srclen, destlen); + case BTRFS_COMPRESS_NONE: + default: + /* +@@ -941,14 +941,23 @@ static int btrfs_decompress_bio(struct compressed_bio *cb) + * start_byte tells us the offset into the compressed data we're interested in + */ + int btrfs_decompress(int type, const u8 *data_in, struct page *dest_page, +- unsigned long start_byte, size_t srclen, size_t destlen) ++ unsigned long dest_pgoff, size_t srclen, size_t destlen) + { ++ struct btrfs_fs_info *fs_info = btrfs_sb(dest_page->mapping->host->i_sb); + struct list_head *workspace; ++ const u32 sectorsize = fs_info->sectorsize; + int ret; + ++ /* ++ * The full destination page range should not exceed the page size. ++ * And the @destlen should not exceed sectorsize, as this is only called for ++ * inline file extents, which should not exceed sectorsize. ++ */ ++ ASSERT(dest_pgoff + destlen <= PAGE_SIZE && destlen <= sectorsize); ++ + workspace = get_workspace(type, 0); + ret = compression_decompress(type, workspace, data_in, dest_page, +- start_byte, srclen, destlen); ++ dest_pgoff, srclen, destlen); + put_workspace(type, workspace); + + return ret; +diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h +index 03bb9d143fa75..609865c940658 100644 +--- a/fs/btrfs/compression.h ++++ b/fs/btrfs/compression.h +@@ -143,7 +143,7 @@ int zlib_compress_pages(struct list_head *ws, struct address_space *mapping, + unsigned long *total_in, unsigned long *total_out); + int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb); + int zlib_decompress(struct list_head *ws, const u8 *data_in, +- struct page *dest_page, unsigned long start_byte, size_t srclen, ++ struct page *dest_page, unsigned long dest_pgoff, size_t srclen, + size_t destlen); + struct list_head *zlib_alloc_workspace(unsigned int level); + void zlib_free_workspace(struct list_head *ws); +diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c +index 6c231a116a29c..9f60d0bbd5306 100644 +--- a/fs/btrfs/zlib.c ++++ b/fs/btrfs/zlib.c +@@ -354,18 +354,13 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb) + } + + int zlib_decompress(struct list_head *ws, const u8 *data_in, +- struct page *dest_page, unsigned long start_byte, size_t srclen, ++ struct page *dest_page, unsigned long dest_pgoff, size_t srclen, + size_t destlen) + { + struct workspace *workspace = list_entry(ws, struct workspace, list); + int ret = 0; + int wbits = MAX_WBITS; +- unsigned long bytes_left; +- unsigned long total_out = 0; +- unsigned long pg_offset = 0; +- +- destlen = min_t(unsigned long, destlen, PAGE_SIZE); +- bytes_left = destlen; ++ unsigned long to_copy; + + workspace->strm.next_in = data_in; + workspace->strm.avail_in = srclen; +@@ -390,60 +385,30 @@ int zlib_decompress(struct list_head *ws, const u8 *data_in, + return -EIO; + } + +- while (bytes_left > 0) { +- unsigned long buf_start; +- unsigned long buf_offset; +- unsigned long bytes; +- +- ret = zlib_inflate(&workspace->strm, Z_NO_FLUSH); +- if (ret != Z_OK && ret != Z_STREAM_END) +- break; +- +- buf_start = total_out; +- total_out = workspace->strm.total_out; +- +- if (total_out == buf_start) { +- ret = -EIO; +- break; +- } +- +- if (total_out <= start_byte) +- goto next; +- +- if (total_out > start_byte && buf_start < start_byte) +- buf_offset = start_byte - buf_start; +- else +- buf_offset = 0; +- +- bytes = min(PAGE_SIZE - pg_offset, +- PAGE_SIZE - (buf_offset % PAGE_SIZE)); +- bytes = min(bytes, bytes_left); ++ /* ++ * Everything (in/out buf) should be at most one sector, there should ++ * be no need to switch any input/output buffer. ++ */ ++ ret = zlib_inflate(&workspace->strm, Z_FINISH); ++ to_copy = min(workspace->strm.total_out, destlen); ++ if (ret != Z_STREAM_END) ++ goto out; + +- memcpy_to_page(dest_page, pg_offset, +- workspace->buf + buf_offset, bytes); ++ memcpy_to_page(dest_page, dest_pgoff, workspace->buf, to_copy); + +- pg_offset += bytes; +- bytes_left -= bytes; +-next: +- workspace->strm.next_out = workspace->buf; +- workspace->strm.avail_out = workspace->buf_size; +- } +- +- if (ret != Z_STREAM_END && bytes_left != 0) ++out: ++ if (unlikely(to_copy != destlen)) { ++ pr_warn_ratelimited("BTRFS: infalte failed, decompressed=%lu expected=%zu\n", ++ to_copy, destlen); + ret = -EIO; +- else ++ } else { + ret = 0; ++ } + + zlib_inflateEnd(&workspace->strm); + +- /* +- * this should only happen if zlib returned fewer bytes than we +- * expected. btrfs_get_block is responsible for zeroing from the +- * end of the inline extent (destlen) to the end of the page +- */ +- if (pg_offset < destlen) { +- memzero_page(dest_page, pg_offset, destlen - pg_offset); +- } ++ if (unlikely(to_copy < destlen)) ++ memzero_page(dest_page, dest_pgoff + to_copy, destlen - to_copy); + return ret; + } + +-- +2.43.0 + diff --git a/queue-6.6/clocksource-drivers-arm_global_timer-guard-against-d.patch b/queue-6.6/clocksource-drivers-arm_global_timer-guard-against-d.patch new file mode 100644 index 00000000000..4c3999be823 --- /dev/null +++ b/queue-6.6/clocksource-drivers-arm_global_timer-guard-against-d.patch @@ -0,0 +1,56 @@ +From 4b4edbb1096e44864dc5e0b4c4975462e6f4f906 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Feb 2024 16:13:35 +0100 +Subject: clocksource/drivers/arm_global_timer: Guard against division by zero + +From: Martin Blumenstingl + +[ Upstream commit e651f2fae33634175fae956d896277cf916f5d09 ] + +The result of the division of new_rate by gt_target_rate can be zero (if +new_rate is smaller than gt_target_rate). Using that result as divisor +without checking can result in a division by zero error. Guard against +this by checking for a zero value earlier. +While here, also change the psv variable to an unsigned long to make +sure we don't overflow the datatype as all other types involved are also +unsiged long. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20240225151336.2728533-3-martin.blumenstingl@googlemail.com +Signed-off-by: Sasha Levin +--- + drivers/clocksource/arm_global_timer.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c +index e1c773bb55359..22a58d35a41fa 100644 +--- a/drivers/clocksource/arm_global_timer.c ++++ b/drivers/clocksource/arm_global_timer.c +@@ -290,18 +290,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb, + switch (event) { + case PRE_RATE_CHANGE: + { +- int psv; ++ unsigned long psv; + +- psv = DIV_ROUND_CLOSEST(ndata->new_rate, +- gt_target_rate); +- +- if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) ++ psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate); ++ if (!psv || ++ abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) + return NOTIFY_BAD; + + psv--; + + /* prescaler within legal range? */ +- if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX) ++ if (psv > GT_CONTROL_PRESCALER_MAX) + return NOTIFY_BAD; + + /* +-- +2.43.0 + diff --git a/queue-6.6/clocksource-make-watchdog-and-suspend-timing-multipl.patch b/queue-6.6/clocksource-make-watchdog-and-suspend-timing-multipl.patch new file mode 100644 index 00000000000..fb7c2fb80a3 --- /dev/null +++ b/queue-6.6/clocksource-make-watchdog-and-suspend-timing-multipl.patch @@ -0,0 +1,143 @@ +From 81d49b1b7497931753cb996b2b9bb4da846b2560 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 08:40:23 +0200 +Subject: clocksource: Make watchdog and suspend-timing multiplication overflow + safe + +From: Adrian Hunter + +[ Upstream commit d0304569fb019d1bcfbbbce1ce6df6b96f04079b ] + +Kernel timekeeping is designed to keep the change in cycles (since the last +timer interrupt) below max_cycles, which prevents multiplication overflow +when converting cycles to nanoseconds. However, if timer interrupts stop, +the clocksource_cyc2ns() calculation will eventually overflow. + +Add protection against that. Simplify by folding together +clocksource_delta() and clocksource_cyc2ns() into cycles_to_nsec_safe(). +Check against max_cycles, falling back to a slower higher precision +calculation. + +Suggested-by: Thomas Gleixner +Signed-off-by: Adrian Hunter +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20240325064023.2997-20-adrian.hunter@intel.com +Signed-off-by: Sasha Levin +--- + kernel/time/clocksource.c | 42 +++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 22 deletions(-) + +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index 3260bbe98894b..aa864999dc21b 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -20,6 +20,16 @@ + #include "tick-internal.h" + #include "timekeeping_internal.h" + ++static noinline u64 cycles_to_nsec_safe(struct clocksource *cs, u64 start, u64 end) ++{ ++ u64 delta = clocksource_delta(end, start, cs->mask); ++ ++ if (likely(delta < cs->max_cycles)) ++ return clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ ++ return mul_u64_u32_shr(delta, cs->mult, cs->shift); ++} ++ + /** + * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks + * @mult: pointer to mult variable +@@ -222,8 +232,8 @@ enum wd_read_status { + static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) + { + unsigned int nretries, max_retries; +- u64 wd_end, wd_end2, wd_delta; + int64_t wd_delay, wd_seq_delay; ++ u64 wd_end, wd_end2; + + max_retries = clocksource_get_max_watchdog_retry(); + for (nretries = 0; nretries <= max_retries; nretries++) { +@@ -234,9 +244,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + wd_end2 = watchdog->read(watchdog); + local_irq_enable(); + +- wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask); +- wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, +- watchdog->shift); ++ wd_delay = cycles_to_nsec_safe(watchdog, *wdnow, wd_end); + if (wd_delay <= WATCHDOG_MAX_SKEW) { + if (nretries > 1 && nretries >= max_retries) { + pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", +@@ -254,8 +262,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + * report system busy, reinit the watchdog and skip the current + * watchdog test. + */ +- wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask); +- wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift); ++ wd_seq_delay = cycles_to_nsec_safe(watchdog, wd_end, wd_end2); + if (wd_seq_delay > WATCHDOG_MAX_SKEW/2) + goto skip_test; + } +@@ -366,8 +373,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + delta = (csnow_end - csnow_mid) & cs->mask; + if (delta < 0) + cpumask_set_cpu(cpu, &cpus_ahead); +- delta = clocksource_delta(csnow_end, csnow_begin, cs->mask); +- cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ cs_nsec = cycles_to_nsec_safe(cs, csnow_begin, csnow_end); + if (cs_nsec > cs_nsec_max) + cs_nsec_max = cs_nsec; + if (cs_nsec < cs_nsec_min) +@@ -398,8 +404,8 @@ static inline void clocksource_reset_watchdog(void) + + static void clocksource_watchdog(struct timer_list *unused) + { +- u64 csnow, wdnow, cslast, wdlast, delta; + int64_t wd_nsec, cs_nsec, interval; ++ u64 csnow, wdnow, cslast, wdlast; + int next_cpu, reset_pending; + struct clocksource *cs; + enum wd_read_status read_ret; +@@ -456,12 +462,8 @@ static void clocksource_watchdog(struct timer_list *unused) + continue; + } + +- delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask); +- wd_nsec = clocksource_cyc2ns(delta, watchdog->mult, +- watchdog->shift); +- +- delta = clocksource_delta(csnow, cs->cs_last, cs->mask); +- cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ wd_nsec = cycles_to_nsec_safe(watchdog, cs->wd_last, wdnow); ++ cs_nsec = cycles_to_nsec_safe(cs, cs->cs_last, csnow); + wdlast = cs->wd_last; /* save these in case we print them */ + cslast = cs->cs_last; + cs->cs_last = csnow; +@@ -832,7 +834,7 @@ void clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles) + */ + u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now) + { +- u64 now, delta, nsec = 0; ++ u64 now, nsec = 0; + + if (!suspend_clocksource) + return 0; +@@ -847,12 +849,8 @@ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now) + else + now = suspend_clocksource->read(suspend_clocksource); + +- if (now > suspend_start) { +- delta = clocksource_delta(now, suspend_start, +- suspend_clocksource->mask); +- nsec = mul_u64_u32_shr(delta, suspend_clocksource->mult, +- suspend_clocksource->shift); +- } ++ if (now > suspend_start) ++ nsec = cycles_to_nsec_safe(suspend_clocksource, suspend_start, now); + + /* + * Disable the suspend timer to save power if current clocksource is +-- +2.43.0 + diff --git a/queue-6.6/drm-amdgpu-fix-dereference-null-return-value-for-the.patch b/queue-6.6/drm-amdgpu-fix-dereference-null-return-value-for-the.patch new file mode 100644 index 00000000000..027674cff73 --- /dev/null +++ b/queue-6.6/drm-amdgpu-fix-dereference-null-return-value-for-the.patch @@ -0,0 +1,49 @@ +From 2b5220893df67dc27009bfaa0950406ee0ff145e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 May 2024 17:14:45 +0800 +Subject: drm/amdgpu: fix dereference null return value for the function + amdgpu_vm_pt_parent +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jesse Zhang + +[ Upstream commit 511a623fb46a6cf578c61d4f2755783c48807c77 ] + +The pointer parent may be NULLed by the function amdgpu_vm_pt_parent. +To make the code more robust, check the pointer parent. + +Signed-off-by: Jesse Zhang +Suggested-by: Christian König +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +index 0d51222f6f8eb..026a3db947298 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c +@@ -766,11 +766,15 @@ int amdgpu_vm_pde_update(struct amdgpu_vm_update_params *params, + struct amdgpu_vm_bo_base *entry) + { + struct amdgpu_vm_bo_base *parent = amdgpu_vm_pt_parent(entry); +- struct amdgpu_bo *bo = parent->bo, *pbo; ++ struct amdgpu_bo *bo, *pbo; + struct amdgpu_vm *vm = params->vm; + uint64_t pde, pt, flags; + unsigned int level; + ++ if (WARN_ON(!parent)) ++ return -EINVAL; ++ ++ bo = parent->bo; + for (level = 0, pbo = bo->parent; pbo; ++level) + pbo = pbo->parent; + +-- +2.43.0 + diff --git a/queue-6.6/drm-amdgpu-gfx11-need-acquire-mutex-before-access-cp.patch b/queue-6.6/drm-amdgpu-gfx11-need-acquire-mutex-before-access-cp.patch new file mode 100644 index 00000000000..5eb0c69a8c6 --- /dev/null +++ b/queue-6.6/drm-amdgpu-gfx11-need-acquire-mutex-before-access-cp.patch @@ -0,0 +1,102 @@ +From 72516630230bee2668c491fdafcac27c565a5ad5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Dec 2023 17:10:34 +0800 +Subject: drm/amdgpu/gfx11: need acquire mutex before access CP_VMID_RESET v2 + +From: Jack Xiao + +[ Upstream commit 4b5c5f5ad38b9435518730cc7f8f1e8de9c5cb2f ] + +It's required to take the gfx mutex before access to CP_VMID_RESET, +for there is a race condition with CP firmware to write the register. + +v2: add extra code to ensure the mutex releasing is successful. + +Signed-off-by: Jack Xiao +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 48 +++++++++++++++++++++++++- + 1 file changed, 47 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +index c81e98f0d17ff..17a09e96b30fc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -4430,11 +4430,43 @@ static int gfx_v11_0_wait_for_idle(void *handle) + return -ETIMEDOUT; + } + ++static int gfx_v11_0_request_gfx_index_mutex(struct amdgpu_device *adev, ++ int req) ++{ ++ u32 i, tmp, val; ++ ++ for (i = 0; i < adev->usec_timeout; i++) { ++ /* Request with MeId=2, PipeId=0 */ ++ tmp = REG_SET_FIELD(0, CP_GFX_INDEX_MUTEX, REQUEST, req); ++ tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX, CLIENTID, 4); ++ WREG32_SOC15(GC, 0, regCP_GFX_INDEX_MUTEX, tmp); ++ ++ val = RREG32_SOC15(GC, 0, regCP_GFX_INDEX_MUTEX); ++ if (req) { ++ if (val == tmp) ++ break; ++ } else { ++ tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX, ++ REQUEST, 1); ++ ++ /* unlocked or locked by firmware */ ++ if (val != tmp) ++ break; ++ } ++ udelay(1); ++ } ++ ++ if (i >= adev->usec_timeout) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static int gfx_v11_0_soft_reset(void *handle) + { + u32 grbm_soft_reset = 0; + u32 tmp; +- int i, j, k; ++ int r, i, j, k; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + tmp = RREG32_SOC15(GC, 0, regCP_INT_CNTL); +@@ -4474,6 +4506,13 @@ static int gfx_v11_0_soft_reset(void *handle) + } + } + ++ /* Try to acquire the gfx mutex before access to CP_VMID_RESET */ ++ r = gfx_v11_0_request_gfx_index_mutex(adev, 1); ++ if (r) { ++ DRM_ERROR("Failed to acquire the gfx mutex during soft reset\n"); ++ return r; ++ } ++ + WREG32_SOC15(GC, 0, regCP_VMID_RESET, 0xfffffffe); + + // Read CP_VMID_RESET register three times. +@@ -4482,6 +4521,13 @@ static int gfx_v11_0_soft_reset(void *handle) + RREG32_SOC15(GC, 0, regCP_VMID_RESET); + RREG32_SOC15(GC, 0, regCP_VMID_RESET); + ++ /* release the gfx mutex */ ++ r = gfx_v11_0_request_gfx_index_mutex(adev, 0); ++ if (r) { ++ DRM_ERROR("Failed to release the gfx mutex during soft reset\n"); ++ return r; ++ } ++ + for (i = 0; i < adev->usec_timeout; i++) { + if (!RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) && + !RREG32_SOC15(GC, 0, regCP_GFX_HQD_ACTIVE)) +-- +2.43.0 + diff --git a/queue-6.6/drm-lima-set-gp-bus_stop-bit-before-hard-reset.patch b/queue-6.6/drm-lima-set-gp-bus_stop-bit-before-hard-reset.patch new file mode 100644 index 00000000000..40dd0ab7c04 --- /dev/null +++ b/queue-6.6/drm-lima-set-gp-bus_stop-bit-before-hard-reset.patch @@ -0,0 +1,55 @@ +From 921f98a47f897097fdfd1f6487056dd97cdd89a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Jan 2024 03:59:43 +0100 +Subject: drm/lima: set gp bus_stop bit before hard reset + +From: Erico Nunes + +[ Upstream commit 27aa58ec85f973d98d336df7b7941149308db80f ] + +This is required for reliable hard resets. Otherwise, doing a hard reset +while a task is still running (such as a task which is being stopped by +the drm_sched timeout handler) may result in random mmu write timeouts +or lockups which cause the entire gpu to hang. + +Signed-off-by: Erico Nunes +Signed-off-by: Qiang Yu +Link: https://patchwork.freedesktop.org/patch/msgid/20240124025947.2110659-5-nunes.erico@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/lima/lima_gp.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index ca3842f719842..82071835ec9ed 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -166,6 +166,11 @@ static void lima_gp_task_run(struct lima_sched_pipe *pipe, + gp_write(LIMA_GP_CMD, cmd); + } + ++static int lima_gp_bus_stop_poll(struct lima_ip *ip) ++{ ++ return !!(gp_read(LIMA_GP_STATUS) & LIMA_GP_STATUS_BUS_STOPPED); ++} ++ + static int lima_gp_hard_reset_poll(struct lima_ip *ip) + { + gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC01A0000); +@@ -179,6 +184,13 @@ static int lima_gp_hard_reset(struct lima_ip *ip) + + gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC0FFE000); + gp_write(LIMA_GP_INT_MASK, 0); ++ ++ gp_write(LIMA_GP_CMD, LIMA_GP_CMD_STOP_BUS); ++ ret = lima_poll_timeout(ip, lima_gp_bus_stop_poll, 10, 100); ++ if (ret) { ++ dev_err(dev->dev, "%s bus stop timeout\n", lima_ip_name(ip)); ++ return ret; ++ } + gp_write(LIMA_GP_CMD, LIMA_GP_CMD_RESET); + ret = lima_poll_timeout(ip, lima_gp_hard_reset_poll, 10, 100); + if (ret) { +-- +2.43.0 + diff --git a/queue-6.6/drm-msm-reduce-fallout-of-fence-signaling-vs-reclaim.patch b/queue-6.6/drm-msm-reduce-fallout-of-fence-signaling-vs-reclaim.patch new file mode 100644 index 00000000000..8c9b90c1ce5 --- /dev/null +++ b/queue-6.6/drm-msm-reduce-fallout-of-fence-signaling-vs-reclaim.patch @@ -0,0 +1,39 @@ +From a73631cf5e20c91c3c855b7ec02be6255b2af987 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Nov 2023 07:14:19 -0800 +Subject: drm/msm: Reduce fallout of fence signaling vs reclaim hangs + +From: Rob Clark + +[ Upstream commit 4bea53b9c7c72fd12a0ceebe88a71723c0a514b8 ] + +Until various PM devfreq/QoS and interconnect patches land, we could +potentially trigger reclaim from gpu scheduler thread, and under enough +memory pressure that could trigger a sort of deadlock. Eventually the +wait will timeout and we'll move on to consider other GEM objects. But +given that there is still a potential for deadlock/stalling, we should +reduce the timeout to contain the damage. + +Signed-off-by: Rob Clark +Patchwork: https://patchwork.freedesktop.org/patch/568031/ +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gem_shrinker.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c +index f38296ad87434..0641f5bb8649a 100644 +--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c ++++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c +@@ -76,7 +76,7 @@ static bool + wait_for_idle(struct drm_gem_object *obj) + { + enum dma_resv_usage usage = dma_resv_usage_rw(true); +- return dma_resv_wait_timeout(obj->resv, usage, false, 1000) > 0; ++ return dma_resv_wait_timeout(obj->resv, usage, false, 10) > 0; + } + + static bool +-- +2.43.0 + diff --git a/queue-6.6/drm-rockchip-vop2-clear-afbc-en-and-transform-bit-fo.patch b/queue-6.6/drm-rockchip-vop2-clear-afbc-en-and-transform-bit-fo.patch new file mode 100644 index 00000000000..9883822b2c2 --- /dev/null +++ b/queue-6.6/drm-rockchip-vop2-clear-afbc-en-and-transform-bit-fo.patch @@ -0,0 +1,46 @@ +From ea3eb04f997af020be37a5f831cb8f1f55e53ddb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Dec 2023 19:57:41 +0800 +Subject: drm/rockchip: vop2: clear afbc en and transform bit for cluster + window at linear mode + +From: Andy Yan + +[ Upstream commit 20529a68307feed00dd3d431d3fff0572616b0f2 ] + +The enable bit and transform offset of cluster windows should be +cleared when it work at linear mode, or we may have a iommu fault +issue on rk3588 which cluster windows switch between afbc and linear +mode. + +As the cluster windows of rk3568 only supports afbc format +so is therefore not affected. + +Signed-off-by: Andy Yan +Reviewed-by: Sascha Hauer +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20231211115741.1784954-1-andyshrk@163.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index f2a956f973613..d1de12e850e74 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1260,6 +1260,11 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, + vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270); + vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90); + } else { ++ if (vop2_cluster_window(win)) { ++ vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 0); ++ vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, 0); ++ } ++ + vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4)); + } + +-- +2.43.0 + diff --git a/queue-6.6/edac-skx_common-allow-decoding-of-sgx-addresses.patch b/queue-6.6/edac-skx_common-allow-decoding-of-sgx-addresses.patch new file mode 100644 index 00000000000..e31916c1fd8 --- /dev/null +++ b/queue-6.6/edac-skx_common-allow-decoding-of-sgx-addresses.patch @@ -0,0 +1,43 @@ +From 98ea0563ec4b4c94f8146f2a15db8501e63ef3c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 20:04:19 +0800 +Subject: EDAC/skx_common: Allow decoding of SGX addresses + +From: Qiuxu Zhuo + +[ Upstream commit e0d335077831196bffe6a634ffe385fc684192ca ] + +There are no "struct page" associations with SGX pages, causing the check +pfn_to_online_page() to fail. This results in the inability to decode the +SGX addresses and warning messages like: + + Invalid address 0x34cc9a98840 in IA32_MC17_ADDR + +Add an additional check to allow the decoding of the error address and to +skip the warning message, if the error address is an SGX address. + +Fixes: 1e92af09fab1 ("EDAC/skx_common: Filter out the invalid address") +Signed-off-by: Qiuxu Zhuo +Signed-off-by: Tony Luck +Link: https://lore.kernel.org/r/20240408120419.50234-1-qiuxu.zhuo@intel.com +Signed-off-by: Sasha Levin +--- + drivers/edac/skx_common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c +index f4b192420be47..8d18099fd528c 100644 +--- a/drivers/edac/skx_common.c ++++ b/drivers/edac/skx_common.c +@@ -659,7 +659,7 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val, + memset(&res, 0, sizeof(res)); + res.mce = mce; + res.addr = mce->addr & MCI_ADDR_PHYSADDR; +- if (!pfn_to_online_page(res.addr >> PAGE_SHIFT)) { ++ if (!pfn_to_online_page(res.addr >> PAGE_SHIFT) && !arch_is_platform_page(res.addr)) { + pr_err("Invalid address 0x%llx in IA32_MC%d_ADDR\n", mce->addr, mce->bank); + return NOTIFY_DONE; + } +-- +2.43.0 + diff --git a/queue-6.6/edac-skx_common-filter-out-the-invalid-address.patch b/queue-6.6/edac-skx_common-filter-out-the-invalid-address.patch new file mode 100644 index 00000000000..4f877cec460 --- /dev/null +++ b/queue-6.6/edac-skx_common-filter-out-the-invalid-address.patch @@ -0,0 +1,42 @@ +From 4bdcc2beebe73b85b41af96d152cd4d96fb92b3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Dec 2023 09:45:12 +0800 +Subject: EDAC/skx_common: Filter out the invalid address + +From: Qiuxu Zhuo + +[ Upstream commit 1e92af09fab1b5589f3a7ae68109e3c6a5ca6c6e ] + +Decoding an invalid address with certain firmware decoders could +cause a #PF (Page Fault) in the EFI runtime context, which could +subsequently hang the system. To make {i10nm,skx}_edac more robust +against such bogus firmware decoders, filter out invalid addresses +before allowing the firmware decoder to process them. + +Suggested-by: Tony Luck +Signed-off-by: Qiuxu Zhuo +Signed-off-by: Tony Luck +Link: https://lore.kernel.org/r/20231207014512.78564-1-qiuxu.zhuo@intel.com +Signed-off-by: Sasha Levin +--- + drivers/edac/skx_common.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c +index 03d7a74ca22dc..f4b192420be47 100644 +--- a/drivers/edac/skx_common.c ++++ b/drivers/edac/skx_common.c +@@ -659,6 +659,10 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val, + memset(&res, 0, sizeof(res)); + res.mce = mce; + res.addr = mce->addr & MCI_ADDR_PHYSADDR; ++ if (!pfn_to_online_page(res.addr >> PAGE_SHIFT)) { ++ pr_err("Invalid address 0x%llx in IA32_MC%d_ADDR\n", mce->addr, mce->bank); ++ return NOTIFY_DONE; ++ } + + /* Try driver decoder first */ + if (!(driver_decode && driver_decode(&res))) { +-- +2.43.0 + diff --git a/queue-6.6/evm-don-t-copy-up-security.evm-xattr.patch b/queue-6.6/evm-don-t-copy-up-security.evm-xattr.patch new file mode 100644 index 00000000000..30fe9f7268d --- /dev/null +++ b/queue-6.6/evm-don-t-copy-up-security.evm-xattr.patch @@ -0,0 +1,83 @@ +From bb937b496f3f12b6c3d3154e7ff955070d22c98b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Dec 2023 06:12:43 -0500 +Subject: evm: don't copy up 'security.evm' xattr + +From: Mimi Zohar + +[ Upstream commit 40ca4ee3136d2d09977d1cab8c0c0e1582c3359d ] + +The security.evm HMAC and the original file signatures contain +filesystem specific data. As a result, the HMAC and signature +are not the same on the stacked and backing filesystems. + +Don't copy up 'security.evm'. + +Reviewed-by: Amir Goldstein +Reviewed-by: Christian Brauner +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + include/linux/evm.h | 6 ++++++ + security/integrity/evm/evm_main.c | 7 +++++++ + security/security.c | 2 +- + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/include/linux/evm.h b/include/linux/evm.h +index 01fc495a83e27..36ec884320d9f 100644 +--- a/include/linux/evm.h ++++ b/include/linux/evm.h +@@ -31,6 +31,7 @@ extern void evm_inode_post_setxattr(struct dentry *dentry, + const char *xattr_name, + const void *xattr_value, + size_t xattr_value_len); ++extern int evm_inode_copy_up_xattr(const char *name); + extern int evm_inode_removexattr(struct mnt_idmap *idmap, + struct dentry *dentry, const char *xattr_name); + extern void evm_inode_post_removexattr(struct dentry *dentry, +@@ -117,6 +118,11 @@ static inline void evm_inode_post_setxattr(struct dentry *dentry, + return; + } + ++static inline int evm_inode_copy_up_xattr(const char *name) ++{ ++ return 0; ++} ++ + static inline int evm_inode_removexattr(struct mnt_idmap *idmap, + struct dentry *dentry, + const char *xattr_name) +diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c +index ff9a939dad8e4..2393230c03aa3 100644 +--- a/security/integrity/evm/evm_main.c ++++ b/security/integrity/evm/evm_main.c +@@ -864,6 +864,13 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid) + evm_update_evmxattr(dentry, NULL, NULL, 0); + } + ++int evm_inode_copy_up_xattr(const char *name) ++{ ++ if (strcmp(name, XATTR_NAME_EVM) == 0) ++ return 1; /* Discard */ ++ return -EOPNOTSUPP; ++} ++ + /* + * evm_inode_init_security - initializes security.evm HMAC value + */ +diff --git a/security/security.c b/security/security.c +index dd26f21b2244b..b6144833c7a8e 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -2539,7 +2539,7 @@ int security_inode_copy_up_xattr(const char *name) + return rc; + } + +- return LSM_RET_DEFAULT(inode_copy_up_xattr); ++ return evm_inode_copy_up_xattr(name); + } + EXPORT_SYMBOL(security_inode_copy_up_xattr); + +-- +2.43.0 + diff --git a/queue-6.6/ext4-do-not-trim-the-group-with-corrupted-block-bitm.patch b/queue-6.6/ext4-do-not-trim-the-group-with-corrupted-block-bitm.patch new file mode 100644 index 00000000000..4d820955a88 --- /dev/null +++ b/queue-6.6/ext4-do-not-trim-the-group-with-corrupted-block-bitm.patch @@ -0,0 +1,38 @@ +From fc2725c07bfabaf6b1105b027f93aabdbded4e9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Jan 2024 22:20:34 +0800 +Subject: ext4: do not trim the group with corrupted block bitmap + +From: Baokun Li + +[ Upstream commit 172202152a125955367393956acf5f4ffd092e0d ] + +Otherwise operating on an incorrupted block bitmap can lead to all sorts +of unknown problems. + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240104142040.2835097-3-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index f55ab800a7539..870397f3de559 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -6953,6 +6953,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) + bool set_trimmed = false; + void *bitmap; + ++ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) ++ return 0; ++ + last = ext4_last_grp_cluster(sb, e4b->bd_group); + bitmap = e4b->bd_bitmap; + if (start == 0 && max >= last) +-- +2.43.0 + diff --git a/queue-6.6/ext4-set-the-type-of-max_zeroout-to-unsigned-int-to-.patch b/queue-6.6/ext4-set-the-type-of-max_zeroout-to-unsigned-int-to-.patch new file mode 100644 index 00000000000..2397e06104b --- /dev/null +++ b/queue-6.6/ext4-set-the-type-of-max_zeroout-to-unsigned-int-to-.patch @@ -0,0 +1,42 @@ +From 6e5ee9225428623f1f2e707c11b25e1d28467aa4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Mar 2024 19:33:24 +0800 +Subject: ext4: set the type of max_zeroout to unsigned int to avoid overflow + +From: Baokun Li + +[ Upstream commit 261341a932d9244cbcd372a3659428c8723e5a49 ] + +The max_zeroout is of type int and the s_extent_max_zeroout_kb is of +type uint, and the s_extent_max_zeroout_kb can be freely modified via +the sysfs interface. When the block size is 1024, max_zeroout may +overflow, so declare it as unsigned int to avoid overflow. + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240319113325.3110393-9-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/extents.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index d393df22431a0..448e0ea49b31d 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3402,9 +3402,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, + struct ext4_extent *ex, *abut_ex; + ext4_lblk_t ee_block, eof_block; + unsigned int ee_len, depth, map_len = map->m_len; +- int allocated = 0, max_zeroout = 0; + int err = 0; + int split_flag = EXT4_EXT_DATA_VALID2; ++ int allocated = 0; ++ unsigned int max_zeroout = 0; + + ext_debug(inode, "logical block %llu, max_blocks %u\n", + (unsigned long long)map->m_lblk, map_len); +-- +2.43.0 + diff --git a/queue-6.6/f2fs-fix-to-do-sanity-check-in-update_sit_entry.patch b/queue-6.6/f2fs-fix-to-do-sanity-check-in-update_sit_entry.patch new file mode 100644 index 00000000000..13b50b9665b --- /dev/null +++ b/queue-6.6/f2fs-fix-to-do-sanity-check-in-update_sit_entry.patch @@ -0,0 +1,50 @@ +From 6786cfd175dcec467105f1208643a7797c8c0231 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Feb 2024 19:59:54 +0800 +Subject: f2fs: fix to do sanity check in update_sit_entry + +From: Zhiguo Niu + +[ Upstream commit 36959d18c3cf09b3c12157c6950e18652067de77 ] + +If GET_SEGNO return NULL_SEGNO for some unecpected case, +update_sit_entry will access invalid memory address, +cause system crash. It is better to do sanity check about +GET_SEGNO just like update_segment_mtime & locate_dirty_segment. + +Also remove some redundant judgment code. + +Signed-off-by: Zhiguo Niu +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index 50c7537eb2250..e3e2c0b2f4959 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2398,6 +2398,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) + #endif + + segno = GET_SEGNO(sbi, blkaddr); ++ if (segno == NULL_SEGNO) ++ return; + + se = get_seg_entry(sbi, segno); + new_vblocks = se->valid_blocks + del; +@@ -3481,8 +3483,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, + * since SSR needs latest valid block information. + */ + update_sit_entry(sbi, *new_blkaddr, 1); +- if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) +- update_sit_entry(sbi, old_blkaddr, -1); ++ update_sit_entry(sbi, old_blkaddr, -1); + + /* + * If the current segment is full, flush it out and replace it with a +-- +2.43.0 + diff --git a/queue-6.6/f2fs-stop-checkpoint-when-get-a-out-of-bounds-segmen.patch b/queue-6.6/f2fs-stop-checkpoint-when-get-a-out-of-bounds-segmen.patch new file mode 100644 index 00000000000..a80feb2d935 --- /dev/null +++ b/queue-6.6/f2fs-stop-checkpoint-when-get-a-out-of-bounds-segmen.patch @@ -0,0 +1,81 @@ +From 3627d5406a21727da70aec3269060d25b8eecd73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Feb 2024 14:11:24 +0800 +Subject: f2fs: stop checkpoint when get a out-of-bounds segment + +From: Zhiguo Niu + +[ Upstream commit f9e28904e6442019043a8e94ec6747a064d06003 ] + +There is low probability that an out-of-bounds segment will be got +on a small-capacity device. In order to prevent subsequent write requests +allocating block address from this invalid segment, which may cause +unexpected issue, stop checkpoint should be performed. + +Also introduce a new stop cp reason: STOP_CP_REASON_NO_SEGMENT. + +Note, f2fs_stop_checkpoint(, false) is complex and it may sleep, so we should +move it outside segmap_lock spinlock coverage in get_new_segment(). + +Signed-off-by: Zhiguo Niu +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 12 +++++++++++- + include/linux/f2fs_fs.h | 1 + + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index 804958c6de34c..50c7537eb2250 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2646,6 +2646,7 @@ static void get_new_segment(struct f2fs_sb_info *sbi, + unsigned int old_zoneno = GET_ZONE_FROM_SEG(sbi, *newseg); + bool init = true; + int i; ++ int ret = 0; + + spin_lock(&free_i->segmap_lock); + +@@ -2670,7 +2671,10 @@ static void get_new_segment(struct f2fs_sb_info *sbi, + if (secno >= MAIN_SECS(sbi)) { + secno = find_first_zero_bit(free_i->free_secmap, + MAIN_SECS(sbi)); +- f2fs_bug_on(sbi, secno >= MAIN_SECS(sbi)); ++ if (secno >= MAIN_SECS(sbi)) { ++ ret = -ENOSPC; ++ goto out_unlock; ++ } + } + segno = GET_SEG_FROM_SEC(sbi, secno); + zoneno = GET_ZONE_FROM_SEC(sbi, secno); +@@ -2700,7 +2704,13 @@ static void get_new_segment(struct f2fs_sb_info *sbi, + f2fs_bug_on(sbi, test_bit(segno, free_i->free_segmap)); + __set_inuse(sbi, segno); + *newseg = segno; ++out_unlock: + spin_unlock(&free_i->segmap_lock); ++ ++ if (ret) { ++ f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_NO_SEGMENT); ++ f2fs_bug_on(sbi, 1); ++ } + } + + static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) +diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h +index 3b04657787d09..1352a24d72ef4 100644 +--- a/include/linux/f2fs_fs.h ++++ b/include/linux/f2fs_fs.h +@@ -76,6 +76,7 @@ enum stop_cp_reason { + STOP_CP_REASON_CORRUPTED_SUMMARY, + STOP_CP_REASON_UPDATE_INODE, + STOP_CP_REASON_FLUSH_FAIL, ++ STOP_CP_REASON_NO_SEGMENT, + STOP_CP_REASON_MAX, + }; + +-- +2.43.0 + diff --git a/queue-6.6/firmware-cirrus-cs_dsp-initialize-debugfs_root-to-in.patch b/queue-6.6/firmware-cirrus-cs_dsp-initialize-debugfs_root-to-in.patch new file mode 100644 index 00000000000..073707e33f2 --- /dev/null +++ b/queue-6.6/firmware-cirrus-cs_dsp-initialize-debugfs_root-to-in.patch @@ -0,0 +1,51 @@ +From 1247ca7bd8c404eca2363846df98b7a801d455c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 10:53:53 +0000 +Subject: firmware: cirrus: cs_dsp: Initialize debugfs_root to invalid + +From: Richard Fitzgerald + +[ Upstream commit 66626b15636b5f5cf3d7f6104799f77462748974 ] + +Initialize debugfs_root to -ENODEV so that if the client never sets a +valid debugfs root the debugfs files will not be created. + +A NULL pointer passed to any of the debugfs_create_*() functions means +"create in the root of debugfs". It doesn't mean "ignore". + +Signed-off-by: Richard Fitzgerald +Link: https://msgid.link/r/20240307105353.40067-1-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/firmware/cirrus/cs_dsp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c +index bd1651e709365..a1da7581adb03 100644 +--- a/drivers/firmware/cirrus/cs_dsp.c ++++ b/drivers/firmware/cirrus/cs_dsp.c +@@ -522,7 +522,7 @@ void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) + { + cs_dsp_debugfs_clear(dsp); + debugfs_remove_recursive(dsp->debugfs_root); +- dsp->debugfs_root = NULL; ++ dsp->debugfs_root = ERR_PTR(-ENODEV); + } + EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP); + #else +@@ -2343,6 +2343,11 @@ static int cs_dsp_common_init(struct cs_dsp *dsp) + + mutex_init(&dsp->pwr_lock); + ++#ifdef CONFIG_DEBUG_FS ++ /* Ensure this is invalid if client never provides a debugfs root */ ++ dsp->debugfs_root = ERR_PTR(-ENODEV); ++#endif ++ + return 0; + } + +-- +2.43.0 + diff --git a/queue-6.6/fs-binfmt_elf_efpic-don-t-use-missing-interpreter-s-.patch b/queue-6.6/fs-binfmt_elf_efpic-don-t-use-missing-interpreter-s-.patch new file mode 100644 index 00000000000..3a88f2f21cd --- /dev/null +++ b/queue-6.6/fs-binfmt_elf_efpic-don-t-use-missing-interpreter-s-.patch @@ -0,0 +1,43 @@ +From 106b71d0de8ed5ac6c97cda221994d120a5125e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 07:06:37 -0800 +Subject: fs: binfmt_elf_efpic: don't use missing interpreter's properties + +From: Max Filippov + +[ Upstream commit 15fd1dc3dadb4268207fa6797e753541aca09a2a ] + +Static FDPIC executable may get an executable stack even when it has +non-executable GNU_STACK segment. This happens when STACK segment has rw +permissions, but does not specify stack size. In that case FDPIC loader +uses permissions of the interpreter's stack, and for static executables +with no interpreter it results in choosing the arch-default permissions +for the stack. + +Fix that by using the interpreter's properties only when the interpreter +is actually used. + +Signed-off-by: Max Filippov +Link: https://lore.kernel.org/r/20240118150637.660461-1-jcmvbkbc@gmail.com +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf_fdpic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c +index 206812ce544ae..96a8b13b57d96 100644 +--- a/fs/binfmt_elf_fdpic.c ++++ b/fs/binfmt_elf_fdpic.c +@@ -320,7 +320,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) + else + executable_stack = EXSTACK_DEFAULT; + +- if (stack_size == 0) { ++ if (stack_size == 0 && interp_params.flags & ELF_FDPIC_FLAG_PRESENT) { + stack_size = interp_params.stack_size; + if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) + executable_stack = EXSTACK_ENABLE_X; +-- +2.43.0 + diff --git a/queue-6.6/fuse-fix-uaf-in-rcu-pathwalks.patch b/queue-6.6/fuse-fix-uaf-in-rcu-pathwalks.patch new file mode 100644 index 00000000000..fe3b4b28817 --- /dev/null +++ b/queue-6.6/fuse-fix-uaf-in-rcu-pathwalks.patch @@ -0,0 +1,105 @@ +From 1024255c46eff5c14d515abc35b358d3888d19ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 00:19:39 -0400 +Subject: fuse: fix UAF in rcu pathwalks + +From: Al Viro + +[ Upstream commit 053fc4f755ad43cf35210677bcba798ccdc48d0c ] + +->permission(), ->get_link() and ->inode_get_acl() might dereference +->s_fs_info (and, in case of ->permission(), ->s_fs_info->fc->user_ns +as well) when called from rcu pathwalk. + +Freeing ->s_fs_info->fc is rcu-delayed; we need to make freeing ->s_fs_info +and dropping ->user_ns rcu-delayed too. + +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/fuse/cuse.c | 3 +-- + fs/fuse/fuse_i.h | 1 + + fs/fuse/inode.c | 15 +++++++++++---- + 3 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c +index 91e89e68177ee..b6cad106c37e4 100644 +--- a/fs/fuse/cuse.c ++++ b/fs/fuse/cuse.c +@@ -474,8 +474,7 @@ static int cuse_send_init(struct cuse_conn *cc) + + static void cuse_fc_release(struct fuse_conn *fc) + { +- struct cuse_conn *cc = fc_to_cc(fc); +- kfree_rcu(cc, fc.rcu); ++ kfree(fc_to_cc(fc)); + } + + /** +diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h +index 3e65cdc946316..4ce1a6fdc94f0 100644 +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -888,6 +888,7 @@ struct fuse_mount { + + /* Entry on fc->mounts */ + struct list_head fc_entry; ++ struct rcu_head rcu; + }; + + static inline struct fuse_mount *get_fuse_mount_super(struct super_block *sb) +diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c +index 04c7ba3ea03a2..735abf426a064 100644 +--- a/fs/fuse/inode.c ++++ b/fs/fuse/inode.c +@@ -952,6 +952,14 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm, + } + EXPORT_SYMBOL_GPL(fuse_conn_init); + ++static void delayed_release(struct rcu_head *p) ++{ ++ struct fuse_conn *fc = container_of(p, struct fuse_conn, rcu); ++ ++ put_user_ns(fc->user_ns); ++ fc->release(fc); ++} ++ + void fuse_conn_put(struct fuse_conn *fc) + { + if (refcount_dec_and_test(&fc->count)) { +@@ -963,13 +971,12 @@ void fuse_conn_put(struct fuse_conn *fc) + if (fiq->ops->release) + fiq->ops->release(fiq); + put_pid_ns(fc->pid_ns); +- put_user_ns(fc->user_ns); + bucket = rcu_dereference_protected(fc->curr_bucket, 1); + if (bucket) { + WARN_ON(atomic_read(&bucket->count) != 1); + kfree(bucket); + } +- fc->release(fc); ++ call_rcu(&fc->rcu, delayed_release); + } + } + EXPORT_SYMBOL_GPL(fuse_conn_put); +@@ -1387,7 +1394,7 @@ EXPORT_SYMBOL_GPL(fuse_send_init); + void fuse_free_conn(struct fuse_conn *fc) + { + WARN_ON(!list_empty(&fc->devices)); +- kfree_rcu(fc, rcu); ++ kfree(fc); + } + EXPORT_SYMBOL_GPL(fuse_free_conn); + +@@ -1921,7 +1928,7 @@ static void fuse_sb_destroy(struct super_block *sb) + void fuse_mount_destroy(struct fuse_mount *fm) + { + fuse_conn_put(fm->fc); +- kfree(fm); ++ kfree_rcu(fm, rcu); + } + EXPORT_SYMBOL(fuse_mount_destroy); + +-- +2.43.0 + diff --git a/queue-6.6/gfs2-refcounting-fix-in-gfs2_thaw_super.patch b/queue-6.6/gfs2-refcounting-fix-in-gfs2_thaw_super.patch new file mode 100644 index 00000000000..1f516920c80 --- /dev/null +++ b/queue-6.6/gfs2-refcounting-fix-in-gfs2_thaw_super.patch @@ -0,0 +1,46 @@ +From 41e6c9d023ce5b88baab9feb30cead957b6ff8a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Dec 2023 20:07:46 +0100 +Subject: gfs2: Refcounting fix in gfs2_thaw_super + +From: Andreas Gruenbacher + +[ Upstream commit 4e58543e7da4859c4ba61d15493e3522b6ad71fd ] + +It turns out that the .freeze_super and .thaw_super operations require +the filesystem to manage the superblock refcount itself. We are using +the freeze_super() and thaw_super() helpers to mostly take care of that +for us, but this means that the superblock may no longer be around by +when thaw_super() returns, and gfs2_thaw_super() will then access freed +memory. Take an extra superblock reference in gfs2_thaw_super() to fix +that. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/super.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index 8b34c6cf9293f..1200cb8059995 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -819,6 +819,7 @@ static int gfs2_thaw_super(struct super_block *sb, enum freeze_holder who) + if (!test_bit(SDF_FREEZE_INITIATOR, &sdp->sd_flags)) + goto out; + ++ atomic_inc(&sb->s_active); + gfs2_freeze_unlock(&sdp->sd_freeze_gh); + + error = gfs2_do_thaw(sdp); +@@ -829,6 +830,7 @@ static int gfs2_thaw_super(struct super_block *sb, enum freeze_holder who) + } + out: + mutex_unlock(&sdp->sd_freeze_mutex); ++ deactivate_super(sb); + return error; + } + +-- +2.43.0 + diff --git a/queue-6.6/gpio-sysfs-extend-the-critical-section-for-unregiste.patch b/queue-6.6/gpio-sysfs-extend-the-critical-section-for-unregiste.patch new file mode 100644 index 00000000000..bd667717d12 --- /dev/null +++ b/queue-6.6/gpio-sysfs-extend-the-critical-section-for-unregiste.patch @@ -0,0 +1,59 @@ +From d4cab131ac1267e6d27989d392dac5fbf8ed8404 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Jan 2024 14:08:45 +0100 +Subject: gpio: sysfs: extend the critical section for unregistering sysfs + devices + +From: Bartosz Golaszewski + +[ Upstream commit 59cba4a0e6ca1058fbf88fec22530a4e2841802a ] + +Checking the gdev->mockdev pointer for NULL must be part of the critical +section. + +Signed-off-by: Bartosz Golaszewski +Reviewed-by: Linus Walleij +Acked-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib-sysfs.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c +index 12d853845bb80..6c27312c62788 100644 +--- a/drivers/gpio/gpiolib-sysfs.c ++++ b/drivers/gpio/gpiolib-sysfs.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + + #include ++#include + #include + #include + #include +@@ -774,15 +775,15 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) + struct gpio_desc *desc; + struct gpio_chip *chip = gdev->chip; + +- if (!gdev->mockdev) +- return; ++ scoped_guard(mutex, &sysfs_lock) { ++ if (!gdev->mockdev) ++ return; + +- device_unregister(gdev->mockdev); ++ device_unregister(gdev->mockdev); + +- /* prevent further gpiod exports */ +- mutex_lock(&sysfs_lock); +- gdev->mockdev = NULL; +- mutex_unlock(&sysfs_lock); ++ /* prevent further gpiod exports */ ++ gdev->mockdev = NULL; ++ } + + /* unregister gpiod class devices owned by sysfs */ + for_each_gpio_desc_with_flag(chip, desc, FLAG_SYSFS) { +-- +2.43.0 + diff --git a/queue-6.6/hrtimer-prevent-queuing-of-hrtimer-without-a-functio.patch b/queue-6.6/hrtimer-prevent-queuing-of-hrtimer-without-a-functio.patch new file mode 100644 index 00000000000..0d683560a7b --- /dev/null +++ b/queue-6.6/hrtimer-prevent-queuing-of-hrtimer-without-a-functio.patch @@ -0,0 +1,44 @@ +From 6325c1222f79b8350aaad4418a781da2b6d52770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jun 2024 21:31:36 +0800 +Subject: hrtimer: Prevent queuing of hrtimer without a function callback + +From: Phil Chang + +[ Upstream commit 5a830bbce3af16833fe0092dec47b6dd30279825 ] + +The hrtimer function callback must not be NULL. It has to be specified by +the call side but it is not validated by the hrtimer code. When a hrtimer +is queued without a function callback, the kernel crashes with a null +pointer dereference when trying to execute the callback in __run_hrtimer(). + +Introduce a validation before queuing the hrtimer in +hrtimer_start_range_ns(). + +[anna-maria: Rephrase commit message] + +Signed-off-by: Phil Chang +Signed-off-by: Anna-Maria Behnsen +Signed-off-by: Thomas Gleixner +Reviewed-by: Anna-Maria Behnsen +Signed-off-by: Sasha Levin +--- + kernel/time/hrtimer.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index 6057fe2e179b0..57e5cb36f1bc9 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1288,6 +1288,8 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, + struct hrtimer_clock_base *base; + unsigned long flags; + ++ if (WARN_ON_ONCE(!timer->function)) ++ return; + /* + * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft + * match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard +-- +2.43.0 + diff --git a/queue-6.6/hrtimer-select-housekeeping-cpu-during-migration.patch b/queue-6.6/hrtimer-select-housekeeping-cpu-during-migration.patch new file mode 100644 index 00000000000..6b7a99ae57c --- /dev/null +++ b/queue-6.6/hrtimer-select-housekeeping-cpu-during-migration.patch @@ -0,0 +1,50 @@ +From ccba8d41540721ca7b69aeacec59ac5cc32c36a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Feb 2024 22:08:56 +0200 +Subject: hrtimer: Select housekeeping CPU during migration + +From: Costa Shulyupin + +[ Upstream commit 56c2cb10120894be40c40a9bf0ce798da14c50f6 ] + +During CPU-down hotplug, hrtimers may migrate to isolated CPUs, +compromising CPU isolation. + +Address this issue by masking valid CPUs for hrtimers using +housekeeping_cpumask(HK_TYPE_TIMER). + +Suggested-by: Waiman Long +Signed-off-by: Costa Shulyupin +Signed-off-by: Thomas Gleixner +Reviewed-by: Waiman Long +Link: https://lore.kernel.org/r/20240222200856.569036-1-costa.shul@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/time/hrtimer.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c +index edb0f821dceaa..6057fe2e179b0 100644 +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2223,8 +2224,8 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, + + int hrtimers_cpu_dying(unsigned int dying_cpu) + { ++ int i, ncpu = cpumask_any_and(cpu_active_mask, housekeeping_cpumask(HK_TYPE_TIMER)); + struct hrtimer_cpu_base *old_base, *new_base; +- int i, ncpu = cpumask_first(cpu_active_mask); + + tick_cancel_sched_timer(dying_cpu); + +-- +2.43.0 + diff --git a/queue-6.6/hwmon-pc87360-bounds-check-data-innr-usage.patch b/queue-6.6/hwmon-pc87360-bounds-check-data-innr-usage.patch new file mode 100644 index 00000000000..3624d6d884c --- /dev/null +++ b/queue-6.6/hwmon-pc87360-bounds-check-data-innr-usage.patch @@ -0,0 +1,60 @@ +From fccf331a5d9f675d96917192022cecd2eb27b5e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Nov 2023 12:02:07 -0800 +Subject: hwmon: (pc87360) Bounds check data->innr usage + +From: Kees Cook + +[ Upstream commit 4265eb062a7303e537ab3792ade31f424c3c5189 ] + +Without visibility into the initializers for data->innr, GCC suspects +using it as an index could walk off the end of the various 14-element +arrays in data. Perform an explicit clamp to the array size. Silences +the following warning with GCC 12+: + +../drivers/hwmon/pc87360.c: In function 'pc87360_update_device': +../drivers/hwmon/pc87360.c:341:49: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] + 341 | data->in_max[i] = pc87360_read_value(data, + | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ + 342 | LD_IN, i, + | ~~~~~~~~~ + 343 | PC87365_REG_IN_MAX); + | ~~~~~~~~~~~~~~~~~~~ +../drivers/hwmon/pc87360.c:209:12: note: at offset 255 into destination object 'in_max' of size 14 + 209 | u8 in_max[14]; /* Register value */ + | ^~~~~~ + +Cc: Jim Cromie +Cc: Jean Delvare +Cc: Guenter Roeck +Cc: linux-hwmon@vger.kernel.org +Signed-off-by: Kees Cook +Reviewed-by: Gustavo A. R. Silva +Link: https://lore.kernel.org/r/20231130200207.work.679-kees@kernel.org +[groeck: Added comment into code clarifying context] +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/pc87360.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c +index a4adc8bd531ff..534a6072036c9 100644 +--- a/drivers/hwmon/pc87360.c ++++ b/drivers/hwmon/pc87360.c +@@ -323,7 +323,11 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) + } + + /* Voltages */ +- for (i = 0; i < data->innr; i++) { ++ /* ++ * The min() below does not have any practical meaning and is ++ * only needed to silence a warning observed with gcc 12+. ++ */ ++ for (i = 0; i < min(data->innr, ARRAY_SIZE(data->in)); i++) { + data->in_status[i] = pc87360_read_value(data, LD_IN, i, + PC87365_REG_IN_STATUS); + /* Clear bits */ +-- +2.43.0 + diff --git a/queue-6.6/ionic-check-cmd_regs-before-copying-in-or-out.patch b/queue-6.6/ionic-check-cmd_regs-before-copying-in-or-out.patch new file mode 100644 index 00000000000..59703fb30df --- /dev/null +++ b/queue-6.6/ionic-check-cmd_regs-before-copying-in-or-out.patch @@ -0,0 +1,129 @@ +From c1f5fb2f553f5b51ff2ace66fb6ac5714ac41cdf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Feb 2024 14:27:41 -0800 +Subject: ionic: check cmd_regs before copying in or out + +From: Shannon Nelson + +[ Upstream commit 7662fad348ac54120e9e6443cb0bbe4f3b582219 ] + +Since we now have potential cases of NULL cmd_regs and info_regs +during a reset recovery, and left NULL if a reset recovery has +failed, we need to check that they exist before we use them. +Most of the cases were covered in the original patch where we +verify before doing the ioreadb() for health or cmd status. +However, we need to protect a few uses of io mem that could +be hit in error recovery or asynchronous threads calls as well +(e.g. ethtool or devlink handlers). + +Fixes: 219e183272b4 ("ionic: no fw read when PCI reset failed") +Reviewed-by: Brett Creeley +Signed-off-by: Shannon Nelson +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/pensando/ionic/ionic_dev.c | 10 ++++++++++ + drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | 7 ++++++- + drivers/net/ethernet/pensando/ionic/ionic_fw.c | 5 +++++ + drivers/net/ethernet/pensando/ionic/ionic_main.c | 3 +++ + 4 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +index b4e0fb25b96d7..e242166f0afe7 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +@@ -319,22 +319,32 @@ int ionic_heartbeat_check(struct ionic *ionic) + + u8 ionic_dev_cmd_status(struct ionic_dev *idev) + { ++ if (!idev->dev_cmd_regs) ++ return (u8)PCI_ERROR_RESPONSE; + return ioread8(&idev->dev_cmd_regs->comp.comp.status); + } + + bool ionic_dev_cmd_done(struct ionic_dev *idev) + { ++ if (!idev->dev_cmd_regs) ++ return false; + return ioread32(&idev->dev_cmd_regs->done) & IONIC_DEV_CMD_DONE; + } + + void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp) + { ++ if (!idev->dev_cmd_regs) ++ return; + memcpy_fromio(comp, &idev->dev_cmd_regs->comp, sizeof(*comp)); + } + + void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd) + { + idev->opcode = cmd->cmd.opcode; ++ ++ if (!idev->dev_cmd_regs) ++ return; ++ + memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd)); + iowrite32(0, &idev->dev_cmd_regs->done); + iowrite32(1, &idev->dev_cmd_regs->doorbell); +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +index 3a6b0a9bc2414..35829a2851fa7 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +@@ -90,18 +90,23 @@ static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs, + void *p) + { + struct ionic_lif *lif = netdev_priv(netdev); ++ struct ionic_dev *idev; + unsigned int offset; + unsigned int size; + + regs->version = IONIC_DEV_CMD_REG_VERSION; + ++ idev = &lif->ionic->idev; ++ if (!idev->dev_info_regs) ++ return; ++ + offset = 0; + size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32); + memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size); + + offset += size; + size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32); +- memcpy_fromio(p + offset, lif->ionic->idev.dev_cmd_regs->words, size); ++ memcpy_fromio(p + offset, idev->dev_cmd_regs->words, size); + } + + static void ionic_get_link_ext_stats(struct net_device *netdev, +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_fw.c b/drivers/net/ethernet/pensando/ionic/ionic_fw.c +index 5f40324cd243f..3c209c1a23373 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_fw.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_fw.c +@@ -109,6 +109,11 @@ int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw, + dl = priv_to_devlink(ionic); + devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0); + ++ if (!idev->dev_cmd_regs) { ++ err = -ENXIO; ++ goto err_out; ++ } ++ + buf_sz = sizeof(idev->dev_cmd_regs->data); + + netdev_dbg(netdev, +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c +index f019277fec572..3ca6893d1bf26 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c +@@ -438,6 +438,9 @@ static void ionic_dev_cmd_clean(struct ionic *ionic) + { + struct ionic_dev *idev = &ionic->idev; + ++ if (!idev->dev_cmd_regs) ++ return; ++ + iowrite32(0, &idev->dev_cmd_regs->doorbell); + memset_io(&idev->dev_cmd_regs->cmd, 0, sizeof(idev->dev_cmd_regs->cmd)); + } +-- +2.43.0 + diff --git a/queue-6.6/ionic-no-fw-read-when-pci-reset-failed.patch b/queue-6.6/ionic-no-fw-read-when-pci-reset-failed.patch new file mode 100644 index 00000000000..df63d34ddac --- /dev/null +++ b/queue-6.6/ionic-no-fw-read-when-pci-reset-failed.patch @@ -0,0 +1,93 @@ +From 01976137761b7b9e7696d182e0f5e25b04d46660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Dec 2023 10:58:01 -0800 +Subject: ionic: no fw read when PCI reset failed + +From: Shannon Nelson + +[ Upstream commit 219e183272b4a566650a37264aff90a8c613d9b5 ] + +If there was a failed attempt to reset the PCI connection, +don't later try to read from PCI as the space is unmapped +and will cause a paging request crash. When clearing the PCI +setup we can clear the dev_info register pointer, and check +it before using it in the fw_running test. + +Signed-off-by: Shannon Nelson +Reviewed-by: Brett Creeley +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../ethernet/pensando/ionic/ionic_bus_pci.c | 5 ++++ + .../net/ethernet/pensando/ionic/ionic_dev.c | 23 +++++++++++++++---- + 2 files changed, 23 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +index f0a7fde8f7fff..a5fa49fd21390 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +@@ -215,6 +215,11 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs) + + static void ionic_clear_pci(struct ionic *ionic) + { ++ ionic->idev.dev_info_regs = NULL; ++ ionic->idev.dev_cmd_regs = NULL; ++ ionic->idev.intr_status = NULL; ++ ionic->idev.intr_ctrl = NULL; ++ + ionic_unmap_bars(ionic); + pci_release_regions(ionic->pdev); + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +index 22ab0a44fa8c7..b4e0fb25b96d7 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c +@@ -165,9 +165,19 @@ void ionic_dev_teardown(struct ionic *ionic) + } + + /* Devcmd Interface */ +-bool ionic_is_fw_running(struct ionic_dev *idev) ++static bool __ionic_is_fw_running(struct ionic_dev *idev, u8 *status_ptr) + { +- u8 fw_status = ioread8(&idev->dev_info_regs->fw_status); ++ u8 fw_status; ++ ++ if (!idev->dev_info_regs) { ++ if (status_ptr) ++ *status_ptr = 0xff; ++ return false; ++ } ++ ++ fw_status = ioread8(&idev->dev_info_regs->fw_status); ++ if (status_ptr) ++ *status_ptr = fw_status; + + /* firmware is useful only if the running bit is set and + * fw_status != 0xff (bad PCI read) +@@ -175,6 +185,11 @@ bool ionic_is_fw_running(struct ionic_dev *idev) + return (fw_status != 0xff) && (fw_status & IONIC_FW_STS_F_RUNNING); + } + ++bool ionic_is_fw_running(struct ionic_dev *idev) ++{ ++ return __ionic_is_fw_running(idev, NULL); ++} ++ + int ionic_heartbeat_check(struct ionic *ionic) + { + unsigned long check_time, last_check_time; +@@ -199,10 +214,8 @@ int ionic_heartbeat_check(struct ionic *ionic) + goto do_check_time; + } + +- fw_status = ioread8(&idev->dev_info_regs->fw_status); +- + /* If fw_status is not ready don't bother with the generation */ +- if (!ionic_is_fw_running(idev)) { ++ if (!__ionic_is_fw_running(idev, &fw_status)) { + fw_status_ready = false; + } else { + fw_generation = fw_status & IONIC_FW_STS_F_GENERATION; +-- +2.43.0 + diff --git a/queue-6.6/ionic-prevent-pci-disable-of-already-disabled-device.patch b/queue-6.6/ionic-prevent-pci-disable-of-already-disabled-device.patch new file mode 100644 index 00000000000..3b1ff09a1b1 --- /dev/null +++ b/queue-6.6/ionic-prevent-pci-disable-of-already-disabled-device.patch @@ -0,0 +1,41 @@ +From f89edb6983a111c3b275c79e73aa3918b70e021a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Dec 2023 10:58:00 -0800 +Subject: ionic: prevent pci disable of already disabled device + +From: Shannon Nelson + +[ Upstream commit 13943d6c82730a2a4e40e05d6deaca26a8de0a4d ] + +If a reset fails, the PCI device is left in a disabled +state, so don't try to disable it again on driver remove. +This prevents a scary looking WARN trace in the kernel log. + + ionic 0000:2b:00.0: disabling already-disabled device + +Signed-off-by: Shannon Nelson +Reviewed-by: Brett Creeley +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +index fa4237c27e061..f0a7fde8f7fff 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +@@ -217,7 +217,9 @@ static void ionic_clear_pci(struct ionic *ionic) + { + ionic_unmap_bars(ionic); + pci_release_regions(ionic->pdev); +- pci_disable_device(ionic->pdev); ++ ++ if (atomic_read(&ionic->pdev->enable_cnt) > 0) ++ pci_disable_device(ionic->pdev); + } + + static int ionic_setup_one(struct ionic *ionic) +-- +2.43.0 + diff --git a/queue-6.6/ionic-use-pci_is_enabled-not-open-code.patch b/queue-6.6/ionic-use-pci_is_enabled-not-open-code.patch new file mode 100644 index 00000000000..3b41c54f45e --- /dev/null +++ b/queue-6.6/ionic-use-pci_is_enabled-not-open-code.patch @@ -0,0 +1,37 @@ +From 93d8e119b99d3d1061b5fd2dcb25437e13b100ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 14:52:59 -0800 +Subject: ionic: use pci_is_enabled not open code + +From: Shannon Nelson + +[ Upstream commit 121e4dcba3700b30e63f25203d09ddfccbab4a09 ] + +Since there is a utility available for this, use +the API rather than open code. + +Fixes: 13943d6c8273 ("ionic: prevent pci disable of already disabled device") +Reviewed-by: Brett Creeley +Signed-off-by: Shannon Nelson +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +index a5fa49fd21390..35099ad5eccc8 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +@@ -223,7 +223,7 @@ static void ionic_clear_pci(struct ionic *ionic) + ionic_unmap_bars(ionic); + pci_release_regions(ionic->pdev); + +- if (atomic_read(&ionic->pdev->enable_cnt) > 0) ++ if (pci_is_enabled(ionic->pdev)) + pci_disable_device(ionic->pdev); + } + +-- +2.43.0 + diff --git a/queue-6.6/irqchip-gic-v3-its-remove-bug_on-in-its_vpe_irq_doma.patch b/queue-6.6/irqchip-gic-v3-its-remove-bug_on-in-its_vpe_irq_doma.patch new file mode 100644 index 00000000000..9a7591e9d2a --- /dev/null +++ b/queue-6.6/irqchip-gic-v3-its-remove-bug_on-in-its_vpe_irq_doma.patch @@ -0,0 +1,41 @@ +From 8dbd60e2c4d90ec587323a89afe1f24e9858ee30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Apr 2024 14:10:53 +0800 +Subject: irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc + +From: Guanrui Huang + +[ Upstream commit 382d2ffe86efb1e2fa803d2cf17e5bfc34e574f3 ] + +This BUG_ON() is useless, because the same effect will be obtained +by letting the code run its course and vm being dereferenced, +triggering an exception. + +So just remove this check. + +Signed-off-by: Guanrui Huang +Signed-off-by: Thomas Gleixner +Reviewed-by: Zenghui Yu +Acked-by: Marc Zyngier +Link: https://lore.kernel.org/r/20240418061053.96803-3-guanrui.huang@linux.alibaba.com +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-gic-v3-its.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c +index c7d6e6987166f..350abbb36e04b 100644 +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -4501,8 +4501,6 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq + struct page *vprop_page; + int base, nr_ids, i, err = 0; + +- BUG_ON(!vm); +- + bitmap = its_lpi_alloc(roundup_pow_of_two(nr_irqs), &base, &nr_ids); + if (!bitmap) + return -ENOMEM; +-- +2.43.0 + diff --git a/queue-6.6/irqchip-renesas-rzg2l-do-not-set-tien-and-tint-sourc.patch b/queue-6.6/irqchip-renesas-rzg2l-do-not-set-tien-and-tint-sourc.patch new file mode 100644 index 00000000000..5ebd688c3f0 --- /dev/null +++ b/queue-6.6/irqchip-renesas-rzg2l-do-not-set-tien-and-tint-sourc.patch @@ -0,0 +1,69 @@ +From edfc08465bf699ba1cf044f298ddea233bbdc8cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Mar 2024 08:50:40 +0000 +Subject: irqchip/renesas-rzg2l: Do not set TIEN and TINT source at the same + time + +From: Biju Das + +[ Upstream commit dce0919c83c325ac9dec5bc8838d5de6d32c01b1 ] + +As per the hardware team, TIEN and TINT source should not set at the same +time due to a possible hardware race leading to spurious IRQ. + +Currently on some scenarios hardware settings for TINT detection is not in +sync with TINT source as the enable/disable overrides source setting value +leading to hardware inconsistent state. For eg: consider the case GPIOINT0 +is used as TINT interrupt and configuring GPIOINT5 as edge type. During +rzg2l_irq_set_type(), TINT source for GPIOINT5 is set. On disable(), +clearing of the entire bytes of TINT source selection for GPIOINT5 is same +as GPIOINT0 with TIEN disabled. Apart from this during enable(), the +setting of GPIOINT5 with TIEN results in spurious IRQ as due to a HW race, +it is possible that IP can use the TIEN with previous source value +(GPIOINT0). + +So, just update TIEN during enable/disable as TINT source is already set +during rzg2l_irq_set_type(). This will make the consistent hardware +settings for detection method tied with TINT source and allows to simplify +the code. + +Signed-off-by: Biju Das +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-renesas-rzg2l.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c +index 02ab6a944539f..ea4b921e5e158 100644 +--- a/drivers/irqchip/irq-renesas-rzg2l.c ++++ b/drivers/irqchip/irq-renesas-rzg2l.c +@@ -132,7 +132,7 @@ static void rzg2l_irqc_irq_disable(struct irq_data *d) + + raw_spin_lock(&priv->lock); + reg = readl_relaxed(priv->base + TSSR(tssr_index)); +- reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset)); ++ reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset)); + writel_relaxed(reg, priv->base + TSSR(tssr_index)); + raw_spin_unlock(&priv->lock); + } +@@ -144,7 +144,6 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d) + unsigned int hw_irq = irqd_to_hwirq(d); + + if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ) { +- unsigned long tint = (uintptr_t)irq_data_get_irq_chip_data(d); + struct rzg2l_irqc_priv *priv = irq_data_to_priv(d); + u32 offset = hw_irq - IRQC_TINT_START; + u32 tssr_offset = TSSR_OFFSET(offset); +@@ -153,7 +152,7 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d) + + raw_spin_lock(&priv->lock); + reg = readl_relaxed(priv->base + TSSR(tssr_index)); +- reg |= (TIEN | tint) << TSSEL_SHIFT(tssr_offset); ++ reg |= TIEN << TSSEL_SHIFT(tssr_offset); + writel_relaxed(reg, priv->base + TSSR(tssr_index)); + raw_spin_unlock(&priv->lock); + } +-- +2.43.0 + diff --git a/queue-6.6/kernfs-fix-false-positive-warn-nr_mmapped-in-kernfs_.patch b/queue-6.6/kernfs-fix-false-positive-warn-nr_mmapped-in-kernfs_.patch new file mode 100644 index 00000000000..7627f35b62d --- /dev/null +++ b/queue-6.6/kernfs-fix-false-positive-warn-nr_mmapped-in-kernfs_.patch @@ -0,0 +1,65 @@ +From 3ae961f0c5130c4beb194ed5e2033253cfb0ae95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Jan 2024 15:46:36 -0800 +Subject: kernfs: fix false-positive WARN(nr_mmapped) in + kernfs_drain_open_files + +From: Neel Natu + +[ Upstream commit 05d8f255867e3196565bb31a911a437697fab094 ] + +Prior to this change 'on->nr_mmapped' tracked the total number of +mmaps across all of its associated open files via kernfs_fop_mmap(). +Thus if the file descriptor associated with a kernfs_open_file was +mmapped 10 times then we would have: 'of->mmapped = true' and +'of_on(of)->nr_mmapped = 10'. + +The problem is that closing or draining a 'of->mmapped' file would +only decrement one from the 'of_on(of)->nr_mmapped' counter. + +For e.g. we have this from kernfs_unlink_open_file(): + if (of->mmapped) + on->nr_mmapped--; + +The WARN_ON_ONCE(on->nr_mmapped) in kernfs_drain_open_files() is +easy to reproduce by: +1. opening a (mmap-able) kernfs file. +2. mmap-ing that file more than once (mapping just once masks the issue). +3. trigger a drain of that kernfs file. + +Modulo out-of-tree patches I was able to trigger this reliably by +identifying pci device nodes in sysfs that have resource regions +that are mmap-able and that don't have any driver attached to them +(steps 1 and 2). For step 3 we can "echo 1 > remove" to trigger a +kernfs_drain. + +Signed-off-by: Neel Natu +Link: https://lore.kernel.org/r/20240127234636.609265-1-neelnatu@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/file.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c +index 180906c36f515..332d08d2fe0d5 100644 +--- a/fs/kernfs/file.c ++++ b/fs/kernfs/file.c +@@ -532,9 +532,11 @@ static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma) + goto out_put; + + rc = 0; +- of->mmapped = true; +- of_on(of)->nr_mmapped++; +- of->vm_ops = vma->vm_ops; ++ if (!of->mmapped) { ++ of->mmapped = true; ++ of_on(of)->nr_mmapped++; ++ of->vm_ops = vma->vm_ops; ++ } + vma->vm_ops = &kernfs_vm_ops; + out_put: + kernfs_put_active(of->kn); +-- +2.43.0 + diff --git a/queue-6.6/md-clean-up-invalid-bug_on-in-md_ioctl.patch b/queue-6.6/md-clean-up-invalid-bug_on-in-md_ioctl.patch new file mode 100644 index 00000000000..ca4861e055a --- /dev/null +++ b/queue-6.6/md-clean-up-invalid-bug_on-in-md_ioctl.patch @@ -0,0 +1,42 @@ +From 070b086f09f1d202a92d2c52db6b5caf992f129f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Feb 2024 11:14:38 +0800 +Subject: md: clean up invalid BUG_ON in md_ioctl + +From: Li Nan + +[ Upstream commit 9dd8702e7cd28ebf076ff838933f29cf671165ec ] + +'disk->private_data' is set to mddev in md_alloc() and never set to NULL, +and users need to open mddev before submitting ioctl. So mddev must not +have been freed during ioctl, and there is no need to check mddev here. +Clean up it. + +Signed-off-by: Li Nan +Reviewed-by: Yu Kuai +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20240226031444.3606764-4-linan666@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 35b003b83ef1b..d1f6770c5cc09 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -7652,11 +7652,6 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode, + + mddev = bdev->bd_disk->private_data; + +- if (!mddev) { +- BUG(); +- goto out; +- } +- + /* Some actions do not requires the mutex */ + switch (cmd) { + case GET_ARRAY_INFO: +-- +2.43.0 + diff --git a/queue-6.6/media-drivers-media-dvb-core-copy-user-arrays-safely.patch b/queue-6.6/media-drivers-media-dvb-core-copy-user-arrays-safely.patch new file mode 100644 index 00000000000..97c55d72576 --- /dev/null +++ b/queue-6.6/media-drivers-media-dvb-core-copy-user-arrays-safely.patch @@ -0,0 +1,70 @@ +From 67f05c4fc490034e3eba43ecf18ce8136478740e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Nov 2023 20:16:34 +0100 +Subject: media: drivers/media/dvb-core: copy user arrays safely + +From: Philipp Stanner + +[ Upstream commit 102fb77c2deb0df3683ef8ff7a6f4cf91dc456e2 ] + +At several positions in dvb_frontend.c, memdup_user() is utilized to +copy userspace arrays. This is done without overflow checks. + +Use the new wrapper memdup_array_user() to copy the arrays more safely. + +Link: https://lore.kernel.org/linux-media/20231102191633.52592-2-pstanner@redhat.com +Suggested-by: Dave Airlie +Signed-off-by: Philipp Stanner +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/dvb-core/dvb_frontend.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c +index 9293b058ab997..93d3378a0df4b 100644 +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -2168,7 +2168,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd, + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + +- tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user(compat_ptr(tvps->props), ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +@@ -2199,7 +2200,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd, + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + +- tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user(compat_ptr(tvps->props), ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +@@ -2379,7 +2381,8 @@ static int dvb_get_property(struct dvb_frontend *fe, struct file *file, + if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS) + return -EINVAL; + +- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user((void __user *)tvps->props, ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +@@ -2457,7 +2460,8 @@ static int dvb_frontend_handle_ioctl(struct file *file, + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + +- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); ++ tvp = memdup_array_user((void __user *)tvps->props, ++ tvps->num, sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + +-- +2.43.0 + diff --git a/queue-6.6/media-pci-cx23885-check-cx23885_vdev_init-return.patch b/queue-6.6/media-pci-cx23885-check-cx23885_vdev_init-return.patch new file mode 100644 index 00000000000..d658efaddc3 --- /dev/null +++ b/queue-6.6/media-pci-cx23885-check-cx23885_vdev_init-return.patch @@ -0,0 +1,50 @@ +From eae1ebe17bf598b75f76b3e60db64053b30af747 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 08:58:49 +0200 +Subject: media: pci: cx23885: check cx23885_vdev_init() return + +From: Hans Verkuil + +[ Upstream commit 15126b916e39b0cb67026b0af3c014bfeb1f76b3 ] + +cx23885_vdev_init() can return a NULL pointer, but that pointer +is used in the next line without a check. + +Add a NULL pointer check and go to the error unwind if it is NULL. + +Signed-off-by: Hans Verkuil +Reported-by: Sicong Huang +Signed-off-by: Sasha Levin +--- + drivers/media/pci/cx23885/cx23885-video.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c +index 9af2c5596121c..51d7d720ec48b 100644 +--- a/drivers/media/pci/cx23885/cx23885-video.c ++++ b/drivers/media/pci/cx23885/cx23885-video.c +@@ -1354,6 +1354,10 @@ int cx23885_video_register(struct cx23885_dev *dev) + /* register Video device */ + dev->video_dev = cx23885_vdev_init(dev, dev->pci, + &cx23885_video_template, "video"); ++ if (!dev->video_dev) { ++ err = -ENOMEM; ++ goto fail_unreg; ++ } + dev->video_dev->queue = &dev->vb2_vidq; + dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | + V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE; +@@ -1382,6 +1386,10 @@ int cx23885_video_register(struct cx23885_dev *dev) + /* register VBI device */ + dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, + &cx23885_vbi_template, "vbi"); ++ if (!dev->vbi_dev) { ++ err = -ENOMEM; ++ goto fail_unreg; ++ } + dev->vbi_dev->queue = &dev->vb2_vbiq; + dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | + V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE; +-- +2.43.0 + diff --git a/queue-6.6/memory-stm32-fmc2-ebi-check-regmap_read-return-value.patch b/queue-6.6/memory-stm32-fmc2-ebi-check-regmap_read-return-value.patch new file mode 100644 index 00000000000..abbf6b0a247 --- /dev/null +++ b/queue-6.6/memory-stm32-fmc2-ebi-check-regmap_read-return-value.patch @@ -0,0 +1,283 @@ +From c1c36d8de4b67cb2b23fd11631dec18238dc81b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Feb 2024 11:14:25 +0100 +Subject: memory: stm32-fmc2-ebi: check regmap_read return value + +From: Christophe Kerello + +[ Upstream commit 722463f73bcf65a8c818752a38c14ee672c77da1 ] + +Check regmap_read return value to avoid to use uninitialized local +variables. + +Signed-off-by: Christophe Kerello +Link: https://lore.kernel.org/r/20240226101428.37791-3-christophe.kerello@foss.st.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + drivers/memory/stm32-fmc2-ebi.c | 122 +++++++++++++++++++++++--------- + 1 file changed, 88 insertions(+), 34 deletions(-) + +diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c +index 9015e8277dc8a..871f3de69102e 100644 +--- a/drivers/memory/stm32-fmc2-ebi.c ++++ b/drivers/memory/stm32-fmc2-ebi.c +@@ -181,8 +181,11 @@ static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if (bcr & FMC2_BCR_MTYP) + return 0; +@@ -195,8 +198,11 @@ static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; +@@ -209,8 +215,11 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if (bcr & FMC2_BCR_BURSTEN) + return 0; +@@ -223,8 +232,11 @@ static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) + return 0; +@@ -237,8 +249,11 @@ static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; +@@ -251,12 +266,18 @@ static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); ++ int ret; ++ ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (prop->reg_type == FMC2_REG_BWTR) +- regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + else +- regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ if (ret) ++ return ret; + + if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) && + ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)) +@@ -270,12 +291,19 @@ static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi, + int cs) + { + u32 bcr, bcr1; ++ int ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); +- if (cs) +- regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); +- else ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; ++ ++ if (cs) { ++ ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); ++ if (ret) ++ return ret; ++ } else { + bcr1 = bcr; ++ } + + if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN))) + return 0; +@@ -307,12 +335,18 @@ static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi, + { + u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup); + u32 bcr, btr, clk_period; ++ int ret; ++ ++ ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr); ++ if (ret) ++ return ret; + +- regmap_read(ebi->regmap, FMC2_BCR1, &bcr); + if (bcr & FMC2_BCR1_CCLKEN || !cs) +- regmap_read(ebi->regmap, FMC2_BTR1, &btr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR1, &btr); + else +- regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); ++ if (ret) ++ return ret; + + clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1; + +@@ -571,11 +605,16 @@ static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi, + if (ret) + return ret; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; ++ + if (prop->reg_type == FMC2_REG_BWTR) +- regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + else +- regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); ++ if (ret) ++ return ret; + + if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN) + val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX); +@@ -693,11 +732,14 @@ static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi, + int cs, u32 setup) + { + u32 old_val, new_val, pcscntr; ++ int ret; + + if (setup < 1) + return 0; + +- regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); ++ ret = regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); ++ if (ret) ++ return ret; + + /* Enable counter for the bank */ + regmap_update_bits(ebi->regmap, FMC2_PCSCNTR, +@@ -944,17 +986,20 @@ static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs) + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0); + } + +-static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) ++static int stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) + { + unsigned int cs; ++ int ret; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { +- regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); +- regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); +- regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); ++ ret |= regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); ++ ret |= regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); ++ if (ret) ++ return ret; + } + +- regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); ++ return regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); + } + + static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi) +@@ -983,22 +1028,29 @@ static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi) + } + + /* NWAIT signal can not be connected to EBI controller and NAND controller */ +-static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) ++static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) + { ++ struct device *dev = ebi->dev; + unsigned int cs; + u32 bcr; ++ int ret; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->bank_assigned & BIT(cs))) + continue; + +- regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); ++ if (ret) ++ return ret; ++ + if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) && +- ebi->bank_assigned & BIT(FMC2_NAND)) +- return true; ++ ebi->bank_assigned & BIT(FMC2_NAND)) { ++ dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); ++ return -EINVAL; ++ } + } + +- return false; ++ return 0; + } + + static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi) +@@ -1085,10 +1137,9 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi) + return -ENODEV; + } + +- if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) { +- dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); +- return -EINVAL; +- } ++ ret = stm32_fmc2_ebi_nwait_used_by_ctrls(ebi); ++ if (ret) ++ return ret; + + stm32_fmc2_ebi_enable(ebi); + +@@ -1133,7 +1184,10 @@ static int stm32_fmc2_ebi_probe(struct platform_device *pdev) + if (ret) + goto err_release; + +- stm32_fmc2_ebi_save_setup(ebi); ++ ret = stm32_fmc2_ebi_save_setup(ebi); ++ if (ret) ++ goto err_release; ++ + platform_set_drvdata(pdev, ebi); + + return 0; +-- +2.43.0 + diff --git a/queue-6.6/memory-tegra-skip-sid-programming-if-sid-registers-a.patch b/queue-6.6/memory-tegra-skip-sid-programming-if-sid-registers-a.patch new file mode 100644 index 00000000000..93286986d24 --- /dev/null +++ b/queue-6.6/memory-tegra-skip-sid-programming-if-sid-registers-a.patch @@ -0,0 +1,39 @@ +From f8c3ba9b91afcdea25e1171e31034313638b1a34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Nov 2023 16:57:13 +0530 +Subject: memory: tegra: Skip SID programming if SID registers aren't set + +From: Ashish Mhetre + +[ Upstream commit 0d6c918011ce4764ed277de4726a468b7ffe5fed ] + +There are few MC clients where SID security and override register +offsets are not specified like "sw_cluster0" in tegra234. Don't program +SID override for such clients because it leads to access to invalid +addresses. + +Signed-off-by: Ashish Mhetre +Link: https://lore.kernel.org/r/20231107112713.21399-2-amhetre@nvidia.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + drivers/memory/tegra/tegra186.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c +index 533f85a4b2bdb..7633481e547d2 100644 +--- a/drivers/memory/tegra/tegra186.c ++++ b/drivers/memory/tegra/tegra186.c +@@ -75,6 +75,9 @@ static void tegra186_mc_client_sid_override(struct tegra_mc *mc, + { + u32 value, old; + ++ if (client->regs.sid.security == 0 && client->regs.sid.override == 0) ++ return; ++ + value = readl(mc->regs + client->regs.sid.security); + if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) { + /* +-- +2.43.0 + diff --git a/queue-6.6/net-hns3-add-checking-for-vf-id-of-mailbox.patch b/queue-6.6/net-hns3-add-checking-for-vf-id-of-mailbox.patch new file mode 100644 index 00000000000..0d0cd503bcc --- /dev/null +++ b/queue-6.6/net-hns3-add-checking-for-vf-id-of-mailbox.patch @@ -0,0 +1,43 @@ +From b3de2db24f6668264b972a584cf30188f7674c9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 09:01:15 +0800 +Subject: net: hns3: add checking for vf id of mailbox + +From: Jian Shen + +[ Upstream commit 4e2969a0d6a7549bc0bc1ebc990588b622c4443d ] + +Add checking for vf id of mailbox, in order to avoid array +out-of-bounds risk. + +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Reviewed-by: Sunil Goutham +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +index 877feee53804f..61e155c4d441e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +@@ -1124,10 +1124,11 @@ void hclge_mbx_handler(struct hclge_dev *hdev) + req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data; + + flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); +- if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B))) { ++ if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B) || ++ req->mbx_src_vfid > hdev->num_req_vfs)) { + dev_warn(&hdev->pdev->dev, +- "dropped invalid mailbox message, code = %u\n", +- req->msg.code); ++ "dropped invalid mailbox message, code = %u, vfid = %u\n", ++ req->msg.code, req->mbx_src_vfid); + + /* dropping/not processing this invalid message */ + crq->desc[crq->next_to_use].flag = 0; +-- +2.43.0 + diff --git a/queue-6.6/net-sun3_82586-avoid-reading-past-buffer-in-debug-ou.patch b/queue-6.6/net-sun3_82586-avoid-reading-past-buffer-in-debug-ou.patch new file mode 100644 index 00000000000..971b0920c54 --- /dev/null +++ b/queue-6.6/net-sun3_82586-avoid-reading-past-buffer-in-debug-ou.patch @@ -0,0 +1,51 @@ +From ea73dd821ee6a5a7c7746102f35fd3c05de6e1b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 08:16:54 -0800 +Subject: net/sun3_82586: Avoid reading past buffer in debug output + +From: Kees Cook + +[ Upstream commit 4bea747f3fbec33c16d369b2f51e55981d7c78d0 ] + +Since NUM_XMIT_BUFFS is always 1, building m68k with sun3_defconfig and +-Warraybounds, this build warning is visible[1]: + +drivers/net/ethernet/i825xx/sun3_82586.c: In function 'sun3_82586_timeout': +drivers/net/ethernet/i825xx/sun3_82586.c:990:122: warning: array subscript 1 is above array bounds of 'volatile struct transmit_cmd_struct *[1]' [-Warray-bounds=] + 990 | printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status)); + | ~~~~~~~~~~~~^~~ +... +drivers/net/ethernet/i825xx/sun3_82586.c:156:46: note: while referencing 'xmit_cmds' + 156 | volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS]; + +Avoid accessing index 1 since it doesn't exist. + +Link: https://github.com/KSPP/linux/issues/325 [1] +Cc: Sam Creasey +Signed-off-by: Kees Cook +Reviewed-by: Simon Horman +Tested-by: Simon Horman # build-tested +Reviewed-by: Gustavo A. R. Silva +Link: https://lore.kernel.org/r/20240206161651.work.876-kees@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/i825xx/sun3_82586.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c +index 5e27470c6b1ef..f2d4669c81cf2 100644 +--- a/drivers/net/ethernet/i825xx/sun3_82586.c ++++ b/drivers/net/ethernet/i825xx/sun3_82586.c +@@ -987,7 +987,7 @@ static void sun3_82586_timeout(struct net_device *dev, unsigned int txqueue) + { + #ifdef DEBUG + printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus); +- printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status)); ++ printk("%s: command-stats: %04x\n", dev->name, swab16(p->xmit_cmds[0]->cmd_status)); + printk("%s: check, whether you set the right interrupt number!\n",dev->name); + #endif + sun3_82586_close(dev); +-- +2.43.0 + diff --git a/queue-6.6/netlink-hold-nlk-cb_mutex-longer-in-__netlink_dump_s.patch b/queue-6.6/netlink-hold-nlk-cb_mutex-longer-in-__netlink_dump_s.patch new file mode 100644 index 00000000000..9f4bce3522a --- /dev/null +++ b/queue-6.6/netlink-hold-nlk-cb_mutex-longer-in-__netlink_dump_s.patch @@ -0,0 +1,80 @@ +From 1802aa568564583ab6a8082bbd1db17a687fe1f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Feb 2024 10:50:13 +0000 +Subject: netlink: hold nlk->cb_mutex longer in __netlink_dump_start() + +From: Eric Dumazet + +[ Upstream commit b5590270068c4324dac4a2b5a4a156e02e21339f ] + +__netlink_dump_start() releases nlk->cb_mutex right before +calling netlink_dump() which grabs it again. + +This seems dangerous, even if KASAN did not bother yet. + +Add a @lock_taken parameter to netlink_dump() to let it +grab the mutex if called from netlink_recvmsg() only. + +Signed-off-by: Eric Dumazet +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/netlink/af_netlink.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 6ae782efb1ee3..db49fc4d42cf7 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -130,7 +130,7 @@ static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = { + "nlk_cb_mutex-MAX_LINKS" + }; + +-static int netlink_dump(struct sock *sk); ++static int netlink_dump(struct sock *sk, bool lock_taken); + + /* nl_table locking explained: + * Lookup and traversal are protected with an RCU read-side lock. Insertion +@@ -1989,7 +1989,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + + if (READ_ONCE(nlk->cb_running) && + atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { +- ret = netlink_dump(sk); ++ ret = netlink_dump(sk, false); + if (ret) { + WRITE_ONCE(sk->sk_err, -ret); + sk_error_report(sk); +@@ -2198,7 +2198,7 @@ static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb, + return 0; + } + +-static int netlink_dump(struct sock *sk) ++static int netlink_dump(struct sock *sk, bool lock_taken) + { + struct netlink_sock *nlk = nlk_sk(sk); + struct netlink_ext_ack extack = {}; +@@ -2210,7 +2210,8 @@ static int netlink_dump(struct sock *sk) + int alloc_min_size; + int alloc_size; + +- mutex_lock(nlk->cb_mutex); ++ if (!lock_taken) ++ mutex_lock(nlk->cb_mutex); + if (!nlk->cb_running) { + err = -EINVAL; + goto errout_skb; +@@ -2367,9 +2368,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, + WRITE_ONCE(nlk->cb_running, true); + nlk->dump_done_errno = INT_MAX; + +- mutex_unlock(nlk->cb_mutex); +- +- ret = netlink_dump(sk); ++ ret = netlink_dump(sk, true); + + sock_put(sk); + +-- +2.43.0 + diff --git a/queue-6.6/nfs-avoid-infinite-loop-in-pnfs_update_layout.patch b/queue-6.6/nfs-avoid-infinite-loop-in-pnfs_update_layout.patch new file mode 100644 index 00000000000..af46d6d4a4f --- /dev/null +++ b/queue-6.6/nfs-avoid-infinite-loop-in-pnfs_update_layout.patch @@ -0,0 +1,49 @@ +From 8a81db0f83585fa3e3658f31b8ad3d7d6e9628c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Feb 2024 11:24:53 +1100 +Subject: NFS: avoid infinite loop in pnfs_update_layout. + +From: NeilBrown + +[ Upstream commit 2fdbc20036acda9e5694db74a032d3c605323005 ] + +If pnfsd_update_layout() is called on a file for which recovery has +failed it will enter a tight infinite loop. + +NFS_LAYOUT_INVALID_STID will be set, nfs4_select_rw_stateid() will +return -EIO, and nfs4_schedule_stateid_recovery() will do nothing, so +nfs4_client_recover_expired_lease() will not wait. So the code will +loop indefinitely. + +Break the loop by testing the validity of the open stateid at the top of +the loop. + +Signed-off-by: NeilBrown +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/pnfs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 9084f156d67bf..664d3128e730c 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1997,6 +1997,14 @@ pnfs_update_layout(struct inode *ino, + } + + lookup_again: ++ if (!nfs4_valid_open_stateid(ctx->state)) { ++ trace_pnfs_update_layout(ino, pos, count, ++ iomode, lo, lseg, ++ PNFS_UPDATE_LAYOUT_INVALID_OPEN); ++ lseg = ERR_PTR(-EIO); ++ goto out; ++ } ++ + lseg = ERR_PTR(nfs4_client_recover_expired_lease(clp)); + if (IS_ERR(lseg)) + goto out; +-- +2.43.0 + diff --git a/queue-6.6/nvme-clear-caller-pointer-on-identify-failure.patch b/queue-6.6/nvme-clear-caller-pointer-on-identify-failure.patch new file mode 100644 index 00000000000..69f8422ff18 --- /dev/null +++ b/queue-6.6/nvme-clear-caller-pointer-on-identify-failure.patch @@ -0,0 +1,46 @@ +From b7cfcc91e3f83d06eabd3c01806adf1f5a8cd1e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Mar 2024 06:20:30 -0800 +Subject: nvme: clear caller pointer on identify failure + +From: Keith Busch + +[ Upstream commit 7e80eb792bd7377a20f204943ac31c77d859be89 ] + +The memory allocated for the identification is freed on failure. Set +it to NULL so the caller doesn't have a pointer to that freed address. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index e969da0a681b4..4e39a58a00458 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1313,8 +1313,10 @@ static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id) + + error = nvme_submit_sync_cmd(dev->admin_q, &c, *id, + sizeof(struct nvme_id_ctrl)); +- if (error) ++ if (error) { + kfree(*id); ++ *id = NULL; ++ } + return error; + } + +@@ -1443,6 +1445,7 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, + if (error) { + dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error); + kfree(*id); ++ *id = NULL; + } + return error; + } +-- +2.43.0 + diff --git a/queue-6.6/nvme-fix-namespace-removal-list.patch b/queue-6.6/nvme-fix-namespace-removal-list.patch new file mode 100644 index 00000000000..cafb0f9c324 --- /dev/null +++ b/queue-6.6/nvme-fix-namespace-removal-list.patch @@ -0,0 +1,48 @@ +From f7fa38be1cfe4e80ebbb53c68c98986397c4b409 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Jun 2024 09:36:50 -0700 +Subject: nvme: fix namespace removal list + +From: Keith Busch + +[ Upstream commit ff0ffe5b7c3c12c6e0cca16652905963ae817b44 ] + +This function wants to move a subset of a list from one element to the +tail into another list. It also needs to use the srcu synchronize +instead of the regular rcu version. Do this one element at a time +because that's the only to do it. + +Fixes: be647e2c76b27f4 ("nvme: use srcu for iterating namespace list") +Reported-by: Venkat Rao Bagalkote +Tested-by: Venkat Rao Bagalkote +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 2a1b555406dff..82509f3679373 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -3810,12 +3810,13 @@ static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl, + + mutex_lock(&ctrl->namespaces_lock); + list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) { +- if (ns->head->ns_id > nsid) +- list_splice_init_rcu(&ns->list, &rm_list, +- synchronize_rcu); ++ if (ns->head->ns_id > nsid) { ++ list_del_rcu(&ns->list); ++ synchronize_srcu(&ctrl->srcu); ++ list_add_tail_rcu(&ns->list, &rm_list); ++ } + } + mutex_unlock(&ctrl->namespaces_lock); +- synchronize_srcu(&ctrl->srcu); + + list_for_each_entry_safe(ns, next, &rm_list, list) + nvme_ns_remove(ns); +-- +2.43.0 + diff --git a/queue-6.6/nvme-use-srcu-for-iterating-namespace-list.patch b/queue-6.6/nvme-use-srcu-for-iterating-namespace-list.patch new file mode 100644 index 00000000000..0ddb31d5efb --- /dev/null +++ b/queue-6.6/nvme-use-srcu-for-iterating-namespace-list.patch @@ -0,0 +1,440 @@ +From 18bdcec3bc90022fb1aa32d5a02c8f27c5ea2eda Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 May 2024 06:41:45 -0700 +Subject: nvme: use srcu for iterating namespace list + +From: Keith Busch + +[ Upstream commit be647e2c76b27f409cdd520f66c95be888b553a3 ] + +The nvme pci driver synchronizes with all the namespace queues during a +reset to ensure that there's no pending timeout work. + +Meanwhile the timeout work potentially iterates those same namespaces to +freeze their queues. + +Each of those namespace iterations use the same read lock. If a write +lock should somehow get between the synchronize and freeze steps, then +forward progress is deadlocked. + +We had been relying on the nvme controller state machine to ensure the +reset work wouldn't conflict with timeout work. That guarantee may be a +bit fragile to rely on, so iterate the namespace lists without taking +potentially circular locks, as reported by lockdep. + +Link: https://lore.kernel.org/all/20220930001943.zdbvolc3gkekfmcv@shindev/ +Reported-by: Shinichiro Kawasaki +Tested-by: Shinichiro Kawasaki +Reviewed-by: Sagi Grimberg +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 99 +++++++++++++++++++++-------------- + drivers/nvme/host/ioctl.c | 15 +++--- + drivers/nvme/host/multipath.c | 21 ++++---- + drivers/nvme/host/nvme.h | 4 +- + 4 files changed, 83 insertions(+), 56 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 4e39a58a00458..2a1b555406dff 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -632,7 +632,7 @@ static void nvme_free_ns(struct kref *kref) + kfree(ns); + } + +-static inline bool nvme_get_ns(struct nvme_ns *ns) ++bool nvme_get_ns(struct nvme_ns *ns) + { + return kref_get_unless_zero(&ns->kref); + } +@@ -3542,9 +3542,10 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info) + struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid) + { + struct nvme_ns *ns, *ret = NULL; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) { ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + if (ns->head->ns_id == nsid) { + if (!nvme_get_ns(ns)) + continue; +@@ -3554,7 +3555,7 @@ struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid) + if (ns->head->ns_id > nsid) + break; + } +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + return ret; + } + EXPORT_SYMBOL_NS_GPL(nvme_find_get_ns, NVME_TARGET_PASSTHRU); +@@ -3568,7 +3569,7 @@ static void nvme_ns_add_to_ctrl_list(struct nvme_ns *ns) + + list_for_each_entry_reverse(tmp, &ns->ctrl->namespaces, list) { + if (tmp->head->ns_id < ns->head->ns_id) { +- list_add(&ns->list, &tmp->list); ++ list_add_rcu(&ns->list, &tmp->list); + return; + } + } +@@ -3634,17 +3635,18 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info) + if (nvme_update_ns_info(ns, info)) + goto out_unlink_ns; + +- down_write(&ctrl->namespaces_rwsem); ++ mutex_lock(&ctrl->namespaces_lock); + /* + * Ensure that no namespaces are added to the ctrl list after the queues + * are frozen, thereby avoiding a deadlock between scan and reset. + */ + if (test_bit(NVME_CTRL_FROZEN, &ctrl->flags)) { +- up_write(&ctrl->namespaces_rwsem); ++ mutex_unlock(&ctrl->namespaces_lock); + goto out_unlink_ns; + } + nvme_ns_add_to_ctrl_list(ns); +- up_write(&ctrl->namespaces_rwsem); ++ mutex_unlock(&ctrl->namespaces_lock); ++ synchronize_srcu(&ctrl->srcu); + nvme_get_ctrl(ctrl); + + if (device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups)) +@@ -3660,9 +3662,10 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info) + + out_cleanup_ns_from_list: + nvme_put_ctrl(ctrl); +- down_write(&ctrl->namespaces_rwsem); +- list_del_init(&ns->list); +- up_write(&ctrl->namespaces_rwsem); ++ mutex_lock(&ctrl->namespaces_lock); ++ list_del_rcu(&ns->list); ++ mutex_unlock(&ctrl->namespaces_lock); ++ synchronize_srcu(&ctrl->srcu); + out_unlink_ns: + mutex_lock(&ctrl->subsys->lock); + list_del_rcu(&ns->siblings); +@@ -3712,9 +3715,10 @@ static void nvme_ns_remove(struct nvme_ns *ns) + nvme_cdev_del(&ns->cdev, &ns->cdev_device); + del_gendisk(ns->disk); + +- down_write(&ns->ctrl->namespaces_rwsem); +- list_del_init(&ns->list); +- up_write(&ns->ctrl->namespaces_rwsem); ++ mutex_lock(&ns->ctrl->namespaces_lock); ++ list_del_rcu(&ns->list); ++ mutex_unlock(&ns->ctrl->namespaces_lock); ++ synchronize_srcu(&ns->ctrl->srcu); + + if (last_path) + nvme_mpath_shutdown_disk(ns->head); +@@ -3804,16 +3808,17 @@ static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl, + struct nvme_ns *ns, *next; + LIST_HEAD(rm_list); + +- down_write(&ctrl->namespaces_rwsem); ++ mutex_lock(&ctrl->namespaces_lock); + list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) { + if (ns->head->ns_id > nsid) +- list_move_tail(&ns->list, &rm_list); ++ list_splice_init_rcu(&ns->list, &rm_list, ++ synchronize_rcu); + } +- up_write(&ctrl->namespaces_rwsem); ++ mutex_unlock(&ctrl->namespaces_lock); ++ synchronize_srcu(&ctrl->srcu); + + list_for_each_entry_safe(ns, next, &rm_list, list) + nvme_ns_remove(ns); +- + } + + static int nvme_scan_ns_list(struct nvme_ctrl *ctrl) +@@ -3983,9 +3988,10 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) + /* this is a no-op when called from the controller reset handler */ + nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING_NOIO); + +- down_write(&ctrl->namespaces_rwsem); +- list_splice_init(&ctrl->namespaces, &ns_list); +- up_write(&ctrl->namespaces_rwsem); ++ mutex_lock(&ctrl->namespaces_lock); ++ list_splice_init_rcu(&ctrl->namespaces, &ns_list, synchronize_rcu); ++ mutex_unlock(&ctrl->namespaces_lock); ++ synchronize_srcu(&ctrl->srcu); + + list_for_each_entry_safe(ns, next, &ns_list, list) + nvme_ns_remove(ns); +@@ -4418,6 +4424,7 @@ static void nvme_free_ctrl(struct device *dev) + + nvme_free_cels(ctrl); + nvme_mpath_uninit(ctrl); ++ cleanup_srcu_struct(&ctrl->srcu); + nvme_auth_stop(ctrl); + nvme_auth_free(ctrl); + __free_page(ctrl->discard_page); +@@ -4449,10 +4456,15 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, + WRITE_ONCE(ctrl->state, NVME_CTRL_NEW); + clear_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags); + spin_lock_init(&ctrl->lock); ++ mutex_init(&ctrl->namespaces_lock); ++ ++ ret = init_srcu_struct(&ctrl->srcu); ++ if (ret) ++ return ret; ++ + mutex_init(&ctrl->scan_lock); + INIT_LIST_HEAD(&ctrl->namespaces); + xa_init(&ctrl->cels); +- init_rwsem(&ctrl->namespaces_rwsem); + ctrl->dev = dev; + ctrl->ops = ops; + ctrl->quirks = quirks; +@@ -4531,6 +4543,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, + out: + if (ctrl->discard_page) + __free_page(ctrl->discard_page); ++ cleanup_srcu_struct(&ctrl->srcu); + return ret; + } + EXPORT_SYMBOL_GPL(nvme_init_ctrl); +@@ -4539,22 +4552,24 @@ EXPORT_SYMBOL_GPL(nvme_init_ctrl); + void nvme_mark_namespaces_dead(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) + blk_mark_disk_dead(ns->disk); +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + } + EXPORT_SYMBOL_GPL(nvme_mark_namespaces_dead); + + void nvme_unfreeze(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) + blk_mq_unfreeze_queue(ns->queue); +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + clear_bit(NVME_CTRL_FROZEN, &ctrl->flags); + } + EXPORT_SYMBOL_GPL(nvme_unfreeze); +@@ -4562,14 +4577,15 @@ EXPORT_SYMBOL_GPL(nvme_unfreeze); + int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) { ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + timeout = blk_mq_freeze_queue_wait_timeout(ns->queue, timeout); + if (timeout <= 0) + break; + } +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + return timeout; + } + EXPORT_SYMBOL_GPL(nvme_wait_freeze_timeout); +@@ -4577,23 +4593,25 @@ EXPORT_SYMBOL_GPL(nvme_wait_freeze_timeout); + void nvme_wait_freeze(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) + blk_mq_freeze_queue_wait(ns->queue); +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + } + EXPORT_SYMBOL_GPL(nvme_wait_freeze); + + void nvme_start_freeze(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + + set_bit(NVME_CTRL_FROZEN, &ctrl->flags); +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) + blk_freeze_queue_start(ns->queue); +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + } + EXPORT_SYMBOL_GPL(nvme_start_freeze); + +@@ -4636,11 +4654,12 @@ EXPORT_SYMBOL_GPL(nvme_unquiesce_admin_queue); + void nvme_sync_io_queues(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) + blk_sync_queue(ns->queue); +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + } + EXPORT_SYMBOL_GPL(nvme_sync_io_queues); + +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index 4939ed35638f1..875dee6ecd408 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -921,15 +921,15 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp, + bool open_for_write) + { + struct nvme_ns *ns; +- int ret; ++ int ret, srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); ++ srcu_idx = srcu_read_lock(&ctrl->srcu); + if (list_empty(&ctrl->namespaces)) { + ret = -ENOTTY; + goto out_unlock; + } + +- ns = list_first_entry(&ctrl->namespaces, struct nvme_ns, list); ++ ns = list_first_or_null_rcu(&ctrl->namespaces, struct nvme_ns, list); + if (ns != list_last_entry(&ctrl->namespaces, struct nvme_ns, list)) { + dev_warn(ctrl->device, + "NVME_IOCTL_IO_CMD not supported when multiple namespaces present!\n"); +@@ -939,15 +939,18 @@ static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp, + + dev_warn(ctrl->device, + "using deprecated NVME_IOCTL_IO_CMD ioctl on the char device!\n"); +- kref_get(&ns->kref); +- up_read(&ctrl->namespaces_rwsem); ++ if (!nvme_get_ns(ns)) { ++ ret = -ENXIO; ++ goto out_unlock; ++ } ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + + ret = nvme_user_cmd(ctrl, ns, argp, 0, open_for_write); + nvme_put_ns(ns); + return ret; + + out_unlock: +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + return ret; + } + +diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c +index 6515fa537ee53..645a6b1322205 100644 +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -151,16 +151,17 @@ void nvme_mpath_end_request(struct request *rq) + void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) { ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + if (!ns->head->disk) + continue; + kblockd_schedule_work(&ns->head->requeue_work); + if (ctrl->state == NVME_CTRL_LIVE) + disk_uevent(ns->head->disk, KOBJ_CHANGE); + } +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + } + + static const char *nvme_ana_state_names[] = { +@@ -194,13 +195,14 @@ bool nvme_mpath_clear_current_path(struct nvme_ns *ns) + void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) + { + struct nvme_ns *ns; ++ int srcu_idx; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) { ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + nvme_mpath_clear_current_path(ns); + kblockd_schedule_work(&ns->head->requeue_work); + } +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + } + + void nvme_mpath_revalidate_paths(struct nvme_ns *ns) +@@ -679,6 +681,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, + u32 nr_nsids = le32_to_cpu(desc->nnsids), n = 0; + unsigned *nr_change_groups = data; + struct nvme_ns *ns; ++ int srcu_idx; + + dev_dbg(ctrl->device, "ANA group %d: %s.\n", + le32_to_cpu(desc->grpid), +@@ -690,8 +693,8 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, + if (!nr_nsids) + return 0; + +- down_read(&ctrl->namespaces_rwsem); +- list_for_each_entry(ns, &ctrl->namespaces, list) { ++ srcu_idx = srcu_read_lock(&ctrl->srcu); ++ list_for_each_entry_rcu(ns, &ctrl->namespaces, list) { + unsigned nsid; + again: + nsid = le32_to_cpu(desc->nsids[n]); +@@ -704,7 +707,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, + if (ns->head->ns_id > nsid) + goto again; + } +- up_read(&ctrl->namespaces_rwsem); ++ srcu_read_unlock(&ctrl->srcu, srcu_idx); + return 0; + } + +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 21c24cd8b1e8a..d2b6975e71fbc 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -280,7 +280,8 @@ struct nvme_ctrl { + struct blk_mq_tag_set *tagset; + struct blk_mq_tag_set *admin_tagset; + struct list_head namespaces; +- struct rw_semaphore namespaces_rwsem; ++ struct mutex namespaces_lock; ++ struct srcu_struct srcu; + struct device ctrl_device; + struct device *device; /* char device */ + #ifdef CONFIG_NVME_HWMON +@@ -1126,6 +1127,7 @@ void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 effects, + struct nvme_command *cmd, int status); + struct nvme_ctrl *nvme_ctrl_from_file(struct file *file); + struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid); ++bool nvme_get_ns(struct nvme_ns *ns); + void nvme_put_ns(struct nvme_ns *ns); + + static inline bool nvme_multi_css(struct nvme_ctrl *ctrl) +-- +2.43.0 + diff --git a/queue-6.6/nvmet-rdma-fix-possible-bad-dereference-when-freeing.patch b/queue-6.6/nvmet-rdma-fix-possible-bad-dereference-when-freeing.patch new file mode 100644 index 00000000000..e3e0d17ba74 --- /dev/null +++ b/queue-6.6/nvmet-rdma-fix-possible-bad-dereference-when-freeing.patch @@ -0,0 +1,85 @@ +From 047c62466bc428967ea52572c14eaf11435fde57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 May 2024 10:53:06 +0300 +Subject: nvmet-rdma: fix possible bad dereference when freeing rsps + +From: Sagi Grimberg + +[ Upstream commit 73964c1d07c054376f1b32a62548571795159148 ] + +It is possible that the host connected and saw a cm established +event and started sending nvme capsules on the qp, however the +ctrl did not yet see an established event. This is why the +rsp_wait_list exists (for async handling of these cmds, we move +them to a pending list). + +Furthermore, it is possible that the ctrl cm times out, resulting +in a connect-error cm event. in this case we hit a bad deref [1] +because in nvmet_rdma_free_rsps we assume that all the responses +are in the free list. + +We are freeing the cmds array anyways, so don't even bother to +remove the rsp from the free_list. It is also guaranteed that we +are not racing anything when we are releasing the queue so no +other context accessing this array should be running. + +[1]: +-- +Workqueue: nvmet-free-wq nvmet_rdma_free_queue_work [nvmet_rdma] +[...] +pc : nvmet_rdma_free_rsps+0x78/0xb8 [nvmet_rdma] +lr : nvmet_rdma_free_queue_work+0x88/0x120 [nvmet_rdma] + Call trace: + nvmet_rdma_free_rsps+0x78/0xb8 [nvmet_rdma] + nvmet_rdma_free_queue_work+0x88/0x120 [nvmet_rdma] + process_one_work+0x1ec/0x4a0 + worker_thread+0x48/0x490 + kthread+0x158/0x160 + ret_from_fork+0x10/0x18 +-- + +Signed-off-by: Sagi Grimberg +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/rdma.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 4597bca43a6d8..a6d55ebb82382 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -473,12 +473,8 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) + return 0; + + out_free: +- while (--i >= 0) { +- struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; +- +- list_del(&rsp->free_list); +- nvmet_rdma_free_rsp(ndev, rsp); +- } ++ while (--i >= 0) ++ nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); + kfree(queue->rsps); + out: + return ret; +@@ -489,12 +485,8 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue) + struct nvmet_rdma_device *ndev = queue->dev; + int i, nr_rsps = queue->recv_queue_size * 2; + +- for (i = 0; i < nr_rsps; i++) { +- struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; +- +- list_del(&rsp->free_list); +- nvmet_rdma_free_rsp(ndev, rsp); +- } ++ for (i = 0; i < nr_rsps; i++) ++ nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); + kfree(queue->rsps); + } + +-- +2.43.0 + diff --git a/queue-6.6/nvmet-tcp-do-not-continue-for-invalid-icreq.patch b/queue-6.6/nvmet-tcp-do-not-continue-for-invalid-icreq.patch new file mode 100644 index 00000000000..cef446dab0e --- /dev/null +++ b/queue-6.6/nvmet-tcp-do-not-continue-for-invalid-icreq.patch @@ -0,0 +1,37 @@ +From 9fb179f8064f26c8a6a1bdc5c8775549f0848768 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Mar 2024 08:11:05 +0100 +Subject: nvmet-tcp: do not continue for invalid icreq + +From: Hannes Reinecke + +[ Upstream commit 0889d13b9e1cbef49e802ae09f3b516911ad82a1 ] + +When the length check for an icreq sqe fails we should not +continue processing but rather return immediately as all +other contents of that sqe cannot be relied on. + +Signed-off-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/tcp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 3d302815c6f36..c65a1f4421f60 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -875,6 +875,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) + pr_err("bad nvme-tcp pdu length (%d)\n", + le32_to_cpu(icreq->hdr.plen)); + nvmet_tcp_fatal_error(queue); ++ return -EPROTO; + } + + if (icreq->pfv != NVME_TCP_PFV_1_0) { +-- +2.43.0 + diff --git a/queue-6.6/nvmet-trace-avoid-dereferencing-pointer-too-early.patch b/queue-6.6/nvmet-trace-avoid-dereferencing-pointer-too-early.patch new file mode 100644 index 00000000000..52fb24eba3e --- /dev/null +++ b/queue-6.6/nvmet-trace-avoid-dereferencing-pointer-too-early.patch @@ -0,0 +1,141 @@ +From 82c4ebcde0e9e4b8392e36caacc8179c3f2c3579 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Dec 2023 16:30:51 +0100 +Subject: nvmet-trace: avoid dereferencing pointer too early + +From: Daniel Wagner + +[ Upstream commit 0e716cec6fb11a14c220ee17c404b67962e902f7 ] + +The first command issued from the host to the target is the fabrics +connect command. At this point, neither the target queue nor the +controller have been allocated. But we already try to trace this command +in nvmet_req_init. + +Reported by KASAN. + +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/trace.c | 6 +++--- + drivers/nvme/target/trace.h | 28 +++++++++++++++++----------- + 2 files changed, 20 insertions(+), 14 deletions(-) + +diff --git a/drivers/nvme/target/trace.c b/drivers/nvme/target/trace.c +index bff454d46255b..6ee1f3db81d04 100644 +--- a/drivers/nvme/target/trace.c ++++ b/drivers/nvme/target/trace.c +@@ -211,7 +211,7 @@ const char *nvmet_trace_disk_name(struct trace_seq *p, char *name) + return ret; + } + +-const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl) ++const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id) + { + const char *ret = trace_seq_buffer_ptr(p); + +@@ -224,8 +224,8 @@ const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl) + * If we can know the extra data of the connect command in this stage, + * we can update this print statement later. + */ +- if (ctrl) +- trace_seq_printf(p, "%d", ctrl->cntlid); ++ if (ctrl_id) ++ trace_seq_printf(p, "%d", ctrl_id); + else + trace_seq_printf(p, "_"); + trace_seq_putc(p, 0); +diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h +index 974d99d47f514..7f7ebf9558e50 100644 +--- a/drivers/nvme/target/trace.h ++++ b/drivers/nvme/target/trace.h +@@ -32,18 +32,24 @@ const char *nvmet_trace_parse_fabrics_cmd(struct trace_seq *p, u8 fctype, + nvmet_trace_parse_nvm_cmd(p, opcode, cdw10) : \ + nvmet_trace_parse_admin_cmd(p, opcode, cdw10))) + +-const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl); +-#define __print_ctrl_name(ctrl) \ +- nvmet_trace_ctrl_name(p, ctrl) ++const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id); ++#define __print_ctrl_id(ctrl_id) \ ++ nvmet_trace_ctrl_id(p, ctrl_id) + + const char *nvmet_trace_disk_name(struct trace_seq *p, char *name); + #define __print_disk_name(name) \ + nvmet_trace_disk_name(p, name) + + #ifndef TRACE_HEADER_MULTI_READ +-static inline struct nvmet_ctrl *nvmet_req_to_ctrl(struct nvmet_req *req) ++static inline u16 nvmet_req_to_ctrl_id(struct nvmet_req *req) + { +- return req->sq->ctrl; ++ /* ++ * The queue and controller pointers are not valid until an association ++ * has been established. ++ */ ++ if (!req->sq || !req->sq->ctrl) ++ return 0; ++ return req->sq->ctrl->cntlid; + } + + static inline void __assign_req_name(char *name, struct nvmet_req *req) +@@ -62,7 +68,7 @@ TRACE_EVENT(nvmet_req_init, + TP_ARGS(req, cmd), + TP_STRUCT__entry( + __field(struct nvme_command *, cmd) +- __field(struct nvmet_ctrl *, ctrl) ++ __field(u16, ctrl_id) + __array(char, disk, DISK_NAME_LEN) + __field(int, qid) + __field(u16, cid) +@@ -75,7 +81,7 @@ TRACE_EVENT(nvmet_req_init, + ), + TP_fast_assign( + __entry->cmd = cmd; +- __entry->ctrl = nvmet_req_to_ctrl(req); ++ __entry->ctrl_id = nvmet_req_to_ctrl_id(req); + __assign_req_name(__entry->disk, req); + __entry->qid = req->sq->qid; + __entry->cid = cmd->common.command_id; +@@ -89,7 +95,7 @@ TRACE_EVENT(nvmet_req_init, + ), + TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " + "meta=%#llx, cmd=(%s, %s)", +- __print_ctrl_name(__entry->ctrl), ++ __print_ctrl_id(__entry->ctrl_id), + __print_disk_name(__entry->disk), + __entry->qid, __entry->cid, __entry->nsid, + __entry->flags, __entry->metadata, +@@ -103,7 +109,7 @@ TRACE_EVENT(nvmet_req_complete, + TP_PROTO(struct nvmet_req *req), + TP_ARGS(req), + TP_STRUCT__entry( +- __field(struct nvmet_ctrl *, ctrl) ++ __field(u16, ctrl_id) + __array(char, disk, DISK_NAME_LEN) + __field(int, qid) + __field(int, cid) +@@ -111,7 +117,7 @@ TRACE_EVENT(nvmet_req_complete, + __field(u16, status) + ), + TP_fast_assign( +- __entry->ctrl = nvmet_req_to_ctrl(req); ++ __entry->ctrl_id = nvmet_req_to_ctrl_id(req); + __entry->qid = req->cq->qid; + __entry->cid = req->cqe->command_id; + __entry->result = le64_to_cpu(req->cqe->result.u64); +@@ -119,7 +125,7 @@ TRACE_EVENT(nvmet_req_complete, + __assign_req_name(__entry->disk, req); + ), + TP_printk("nvmet%s: %sqid=%d, cmdid=%u, res=%#llx, status=%#x", +- __print_ctrl_name(__entry->ctrl), ++ __print_ctrl_id(__entry->ctrl_id), + __print_disk_name(__entry->disk), + __entry->qid, __entry->cid, __entry->result, __entry->status) + +-- +2.43.0 + diff --git a/queue-6.6/openrisc-call-setup_memory-earlier-in-the-init-seque.patch b/queue-6.6/openrisc-call-setup_memory-earlier-in-the-init-seque.patch new file mode 100644 index 00000000000..77c784c0694 --- /dev/null +++ b/queue-6.6/openrisc-call-setup_memory-earlier-in-the-init-seque.patch @@ -0,0 +1,54 @@ +From d762653220bcc110b5623c4fcf4a4e32502e8f72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Feb 2024 16:29:30 -0800 +Subject: openrisc: Call setup_memory() earlier in the init sequence + +From: Oreoluwa Babatunde + +[ Upstream commit 7b432bf376c9c198a7ff48f1ed14a14c0ffbe1fe ] + +The unflatten_and_copy_device_tree() function contains a call to +memblock_alloc(). This means that memblock is allocating memory before +any of the reserved memory regions are set aside in the setup_memory() +function which calls early_init_fdt_scan_reserved_mem(). Therefore, +there is a possibility for memblock to allocate from any of the +reserved memory regions. + +Hence, move the call to setup_memory() to be earlier in the init +sequence so that the reserved memory regions are set aside before any +allocations are done using memblock. + +Signed-off-by: Oreoluwa Babatunde +Signed-off-by: Stafford Horne +Signed-off-by: Sasha Levin +--- + arch/openrisc/kernel/setup.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c +index 9cf7fb60441f8..be56eaafc8b95 100644 +--- a/arch/openrisc/kernel/setup.c ++++ b/arch/openrisc/kernel/setup.c +@@ -255,6 +255,9 @@ void calibrate_delay(void) + + void __init setup_arch(char **cmdline_p) + { ++ /* setup memblock allocator */ ++ setup_memory(); ++ + unflatten_and_copy_device_tree(); + + setup_cpuinfo(); +@@ -278,9 +281,6 @@ void __init setup_arch(char **cmdline_p) + } + #endif + +- /* setup memblock allocator */ +- setup_memory(); +- + /* paging_init() sets up the MMU and marks all pages as reserved */ + paging_init(); + +-- +2.43.0 + diff --git a/queue-6.6/parisc-use-irq_enter_rcu-to-fix-warning-at-kernel-co.patch b/queue-6.6/parisc-use-irq_enter_rcu-to-fix-warning-at-kernel-co.patch new file mode 100644 index 00000000000..b735d7456b0 --- /dev/null +++ b/queue-6.6/parisc-use-irq_enter_rcu-to-fix-warning-at-kernel-co.patch @@ -0,0 +1,60 @@ +From f893ca312181373a0722b7a6a97d0330398b922e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Nov 2023 23:16:00 +0100 +Subject: parisc: Use irq_enter_rcu() to fix warning at + kernel/context_tracking.c:367 + +From: Helge Deller + +[ Upstream commit 73cb4a2d8d7e0259f94046116727084f21e4599f ] + +Use irq*_rcu() functions to fix this kernel warning: + + WARNING: CPU: 0 PID: 0 at kernel/context_tracking.c:367 ct_irq_enter+0xa0/0xd0 + Modules linked in: + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.7.0-rc3-64bit+ #1037 + Hardware name: 9000/785/C3700 + + IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000412cd758 00000000412cd75c + IIR: 03ffe01f ISR: 0000000000000000 IOR: 0000000043c20c20 + CPU: 0 CR30: 0000000041caa000 CR31: 0000000000000000 + ORIG_R28: 0000000000000005 + IAOQ[0]: ct_irq_enter+0xa0/0xd0 + IAOQ[1]: ct_irq_enter+0xa4/0xd0 + RP(r2): irq_enter+0x34/0x68 + Backtrace: + [<000000004034a3ec>] irq_enter+0x34/0x68 + [<000000004030dc48>] do_cpu_irq_mask+0xc0/0x450 + [<0000000040303070>] intr_return+0x0/0xc + +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + arch/parisc/kernel/irq.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c +index 2f81bfd4f15e1..dff66be65d290 100644 +--- a/arch/parisc/kernel/irq.c ++++ b/arch/parisc/kernel/irq.c +@@ -498,7 +498,7 @@ asmlinkage void do_cpu_irq_mask(struct pt_regs *regs) + + old_regs = set_irq_regs(regs); + local_irq_disable(); +- irq_enter(); ++ irq_enter_rcu(); + + eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu); + if (!eirr_val) +@@ -533,7 +533,7 @@ asmlinkage void do_cpu_irq_mask(struct pt_regs *regs) + #endif /* CONFIG_IRQSTACKS */ + + out: +- irq_exit(); ++ irq_exit_rcu(); + set_irq_regs(old_regs); + return; + +-- +2.43.0 + diff --git a/queue-6.6/platform-x86-lg-laptop-fix-s-null-argument-warning.patch b/queue-6.6/platform-x86-lg-laptop-fix-s-null-argument-warning.patch new file mode 100644 index 00000000000..a5a2289317d --- /dev/null +++ b/queue-6.6/platform-x86-lg-laptop-fix-s-null-argument-warning.patch @@ -0,0 +1,44 @@ +From 0386a823df8668d9199ac3e77f412ed80482db2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Apr 2024 16:34:27 +0200 +Subject: platform/x86: lg-laptop: fix %s null argument warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gergo Koteles + +[ Upstream commit e71c8481692582c70cdfd0996c20cdcc71e425d3 ] + +W=1 warns about null argument to kprintf: +warning: ‘%s’ directive argument is null [-Wformat-overflow=] +pr_info("product: %s year: %d\n", product, year); + +Use "unknown" instead of NULL. + +Signed-off-by: Gergo Koteles +Reviewed-by: Kuppuswamy Sathyanarayanan +Link: https://lore.kernel.org/r/33d40e976f08f82b9227d0ecae38c787fcc0c0b2.1712154684.git.soyer@irl.hu +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/lg-laptop.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/lg-laptop.c b/drivers/platform/x86/lg-laptop.c +index a1e27334cdf54..78c48a1f9c68a 100644 +--- a/drivers/platform/x86/lg-laptop.c ++++ b/drivers/platform/x86/lg-laptop.c +@@ -715,7 +715,7 @@ static int acpi_add(struct acpi_device *device) + default: + year = 2019; + } +- pr_info("product: %s year: %d\n", product, year); ++ pr_info("product: %s year: %d\n", product ?: "unknown", year); + + if (year >= 2019) + battery_limit_use_wmbb = 1; +-- +2.43.0 + diff --git a/queue-6.6/powerpc-boot-handle-allocation-failure-in-simple_rea.patch b/queue-6.6/powerpc-boot-handle-allocation-failure-in-simple_rea.patch new file mode 100644 index 00000000000..b4019c90e3a --- /dev/null +++ b/queue-6.6/powerpc-boot-handle-allocation-failure-in-simple_rea.patch @@ -0,0 +1,39 @@ +From 2bfba6413e948f874f8a531d583577a2c5d354b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Dec 2022 10:18:16 +0800 +Subject: powerpc/boot: Handle allocation failure in simple_realloc() + +From: Li zeming + +[ Upstream commit 69b0194ccec033c208b071e019032c1919c2822d ] + +simple_malloc() will return NULL when there is not enough memory left. +Check pointer 'new' before using it to copy the old data. + +Signed-off-by: Li zeming +[mpe: Reword subject, use change log from Christophe] +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20221219021816.3012-1-zeming@nfschina.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/boot/simple_alloc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c +index 267d6524caac4..db9aaa5face3f 100644 +--- a/arch/powerpc/boot/simple_alloc.c ++++ b/arch/powerpc/boot/simple_alloc.c +@@ -112,7 +112,9 @@ static void *simple_realloc(void *ptr, unsigned long size) + return ptr; + + new = simple_malloc(size); +- memcpy(new, ptr, p->size); ++ if (new) ++ memcpy(new, ptr, p->size); ++ + simple_free(ptr); + return new; + } +-- +2.43.0 + diff --git a/queue-6.6/powerpc-boot-only-free-if-realloc-succeeds.patch b/queue-6.6/powerpc-boot-only-free-if-realloc-succeeds.patch new file mode 100644 index 00000000000..88bf3f6a48d --- /dev/null +++ b/queue-6.6/powerpc-boot-only-free-if-realloc-succeeds.patch @@ -0,0 +1,43 @@ +From b428e0da39cefe4ab679fde699326e6043f3ca74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Feb 2024 22:51:49 +1100 +Subject: powerpc/boot: Only free if realloc() succeeds + +From: Michael Ellerman + +[ Upstream commit f2d5bccaca3e8c09c9b9c8485375f7bdbb2631d2 ] + +simple_realloc() frees the original buffer (ptr) even if the +reallocation failed. + +Fix it to behave like standard realloc() and only free the original +buffer if the reallocation succeeded. + +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20240229115149.749264-1-mpe@ellerman.id.au +Signed-off-by: Sasha Levin +--- + arch/powerpc/boot/simple_alloc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c +index db9aaa5face3f..d07796fdf91aa 100644 +--- a/arch/powerpc/boot/simple_alloc.c ++++ b/arch/powerpc/boot/simple_alloc.c +@@ -112,10 +112,11 @@ static void *simple_realloc(void *ptr, unsigned long size) + return ptr; + + new = simple_malloc(size); +- if (new) ++ if (new) { + memcpy(new, ptr, p->size); ++ simple_free(ptr); ++ } + +- simple_free(ptr); + return new; + } + +-- +2.43.0 + diff --git a/queue-6.6/powerpc-pseries-papr-sysparm-validate-buffer-object-.patch b/queue-6.6/powerpc-pseries-papr-sysparm-validate-buffer-object-.patch new file mode 100644 index 00000000000..e874657462f --- /dev/null +++ b/queue-6.6/powerpc-pseries-papr-sysparm-validate-buffer-object-.patch @@ -0,0 +1,116 @@ +From 90bb09ce989027ce9fed10e2a784af535e0a81f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Dec 2023 11:01:57 -0600 +Subject: powerpc/pseries/papr-sysparm: Validate buffer object lengths + +From: Nathan Lynch + +[ Upstream commit 35aae182bd7b422be3cefc08c12207bf2b973364 ] + +The ability to get and set system parameters will be exposed to user +space, so let's get a little more strict about malformed +papr_sysparm_buf objects. + +* Create accessors for the length field of struct papr_sysparm_buf. + The length is always stored in MSB order and this is better than + spreading the necessary conversions all over. + +* Reject attempts to submit invalid buffers to RTAS. + +* Warn if RTAS returns a buffer with an invalid length, clamping the + returned length to a safe value that won't overrun the buffer. + +These are meant as precautionary measures to mitigate both firmware +and kernel bugs in this area, should they arise, but I am not aware of +any. + +Signed-off-by: Nathan Lynch +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20231212-papr-sys_rtas-vs-lockdown-v6-10-e9eafd0c8c6c@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/platforms/pseries/papr-sysparm.c | 47 +++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/arch/powerpc/platforms/pseries/papr-sysparm.c b/arch/powerpc/platforms/pseries/papr-sysparm.c +index fedc61599e6cc..a1e7aeac74161 100644 +--- a/arch/powerpc/platforms/pseries/papr-sysparm.c ++++ b/arch/powerpc/platforms/pseries/papr-sysparm.c +@@ -23,6 +23,46 @@ void papr_sysparm_buf_free(struct papr_sysparm_buf *buf) + kfree(buf); + } + ++static size_t papr_sysparm_buf_get_length(const struct papr_sysparm_buf *buf) ++{ ++ return be16_to_cpu(buf->len); ++} ++ ++static void papr_sysparm_buf_set_length(struct papr_sysparm_buf *buf, size_t length) ++{ ++ WARN_ONCE(length > sizeof(buf->val), ++ "bogus length %zu, clamping to safe value", length); ++ length = min(sizeof(buf->val), length); ++ buf->len = cpu_to_be16(length); ++} ++ ++/* ++ * For use on buffers returned from ibm,get-system-parameter before ++ * returning them to callers. Ensures the encoded length of valid data ++ * cannot overrun buf->val[]. ++ */ ++static void papr_sysparm_buf_clamp_length(struct papr_sysparm_buf *buf) ++{ ++ papr_sysparm_buf_set_length(buf, papr_sysparm_buf_get_length(buf)); ++} ++ ++/* ++ * Perform some basic diligence on the system parameter buffer before ++ * submitting it to RTAS. ++ */ ++static bool papr_sysparm_buf_can_submit(const struct papr_sysparm_buf *buf) ++{ ++ /* ++ * Firmware ought to reject buffer lengths that exceed the ++ * maximum specified in PAPR, but there's no reason for the ++ * kernel to allow them either. ++ */ ++ if (papr_sysparm_buf_get_length(buf) > sizeof(buf->val)) ++ return false; ++ ++ return true; ++} ++ + /** + * papr_sysparm_get() - Retrieve the value of a PAPR system parameter. + * @param: PAPR system parameter token as described in +@@ -63,6 +103,9 @@ int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf) + if (token == RTAS_UNKNOWN_SERVICE) + return -ENOENT; + ++ if (!papr_sysparm_buf_can_submit(buf)) ++ return -EINVAL; ++ + work_area = rtas_work_area_alloc(sizeof(*buf)); + + memcpy(rtas_work_area_raw_buf(work_area), buf, sizeof(*buf)); +@@ -77,6 +120,7 @@ int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf) + case 0: + ret = 0; + memcpy(buf, rtas_work_area_raw_buf(work_area), sizeof(*buf)); ++ papr_sysparm_buf_clamp_length(buf); + break; + case -3: /* parameter not implemented */ + ret = -EOPNOTSUPP; +@@ -115,6 +159,9 @@ int papr_sysparm_set(papr_sysparm_t param, const struct papr_sysparm_buf *buf) + if (token == RTAS_UNKNOWN_SERVICE) + return -ENOENT; + ++ if (!papr_sysparm_buf_can_submit(buf)) ++ return -EINVAL; ++ + work_area = rtas_work_area_alloc(sizeof(*buf)); + + memcpy(rtas_work_area_raw_buf(work_area), buf, sizeof(*buf)); +-- +2.43.0 + diff --git a/queue-6.6/powerpc-xics-check-return-value-of-kasprintf-in-icp_.patch b/queue-6.6/powerpc-xics-check-return-value-of-kasprintf-in-icp_.patch new file mode 100644 index 00000000000..1bab65201bf --- /dev/null +++ b/queue-6.6/powerpc-xics-check-return-value-of-kasprintf-in-icp_.patch @@ -0,0 +1,38 @@ +From 7291ffc6d42c623cbcca8910b81f86766e964db7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Nov 2023 11:06:51 +0800 +Subject: powerpc/xics: Check return value of kasprintf in + icp_native_map_one_cpu + +From: Kunwu Chan + +[ Upstream commit 45b1ba7e5d1f6881050d558baf9bc74a2ae13930 ] + +kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. Ensure the allocation was successful +by checking the pointer validity. + +Signed-off-by: Kunwu Chan +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20231122030651.3818-1-chentao@kylinos.cn +Signed-off-by: Sasha Levin +--- + arch/powerpc/sysdev/xics/icp-native.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c +index f6ec6dba92dcb..700b67476a7d8 100644 +--- a/arch/powerpc/sysdev/xics/icp-native.c ++++ b/arch/powerpc/sysdev/xics/icp-native.c +@@ -236,6 +236,8 @@ static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr, + rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation", + cpu, hw_id); + ++ if (!rname) ++ return -ENOMEM; + if (!request_mem_region(addr, size, rname)) { + pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n", + cpu, hw_id); +-- +2.43.0 + diff --git a/queue-6.6/quota-remove-bug_on-from-dqget.patch b/queue-6.6/quota-remove-bug_on-from-dqget.patch new file mode 100644 index 00000000000..ddaf19cda21 --- /dev/null +++ b/queue-6.6/quota-remove-bug_on-from-dqget.patch @@ -0,0 +1,40 @@ +From e3f7778286e796bb04b8c1f35b5f20a4dbd35622 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 13:34:08 +0200 +Subject: quota: Remove BUG_ON from dqget() + +From: Jan Kara + +[ Upstream commit 249f374eb9b6b969c64212dd860cc1439674c4a8 ] + +dqget() checks whether dquot->dq_sb is set when returning it using +BUG_ON. Firstly this doesn't work as an invalidation check for quite +some time (we release dquot with dq_sb set these days), secondly using +BUG_ON is quite harsh. Use WARN_ON_ONCE and check whether dquot is still +hashed instead. + +Signed-off-by: Jan Kara +Signed-off-by: Sasha Levin +--- + fs/quota/dquot.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index 7a2c9b153be6e..23dbde1de2520 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -995,9 +995,8 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid) + * smp_mb__before_atomic() in dquot_acquire(). + */ + smp_rmb(); +-#ifdef CONFIG_QUOTA_DEBUG +- BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ +-#endif ++ /* Has somebody invalidated entry under us? */ ++ WARN_ON_ONCE(hlist_unhashed(&dquot->dq_hash)); + out: + if (empty) + do_destroy_dquot(empty); +-- +2.43.0 + diff --git a/queue-6.6/revert-bpf-sockmap-prevent-lock-inversion-deadlock-i.patch b/queue-6.6/revert-bpf-sockmap-prevent-lock-inversion-deadlock-i.patch new file mode 100644 index 00000000000..c6f6965a948 --- /dev/null +++ b/queue-6.6/revert-bpf-sockmap-prevent-lock-inversion-deadlock-i.patch @@ -0,0 +1,52 @@ +From adcf1ec1c6c92860ec9544fd2375fa0840b03d69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 13:20:08 +0200 +Subject: Revert "bpf, sockmap: Prevent lock inversion deadlock in map delete + elem" + +From: Jakub Sitnicki + +[ Upstream commit 3b9ce0491a43e9af7f108b2f1bced7cd35931660 ] + +This reverts commit ff91059932401894e6c86341915615c5eb0eca48. + +This check is no longer needed. BPF programs attached to tracepoints are +now rejected by the verifier when they attempt to delete from a +sockmap/sockhash maps. + +Signed-off-by: Jakub Sitnicki +Signed-off-by: Daniel Borkmann +Acked-by: John Fastabend +Link: https://lore.kernel.org/bpf/20240527-sockmap-verify-deletes-v1-2-944b372f2101@cloudflare.com +Signed-off-by: Sasha Levin +--- + net/core/sock_map.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index 01be07b485fad..a37143d181f95 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -411,9 +411,6 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test, + struct sock *sk; + int err = 0; + +- if (irqs_disabled()) +- return -EOPNOTSUPP; /* locks here are hardirq-unsafe */ +- + spin_lock_bh(&stab->lock); + sk = *psk; + if (!sk_test || sk_test == sk) +@@ -936,9 +933,6 @@ static long sock_hash_delete_elem(struct bpf_map *map, void *key) + struct bpf_shtab_elem *elem; + int ret = -ENOENT; + +- if (irqs_disabled()) +- return -EOPNOTSUPP; /* locks here are hardirq-unsafe */ +- + hash = sock_hash_bucket_hash(key, key_size); + bucket = sock_hash_select_bucket(htab, hash); + +-- +2.43.0 + diff --git a/queue-6.6/riscv-blacklist-assembly-symbols-for-kprobe.patch b/queue-6.6/riscv-blacklist-assembly-symbols-for-kprobe.patch new file mode 100644 index 00000000000..51f18c80ee1 --- /dev/null +++ b/queue-6.6/riscv-blacklist-assembly-symbols-for-kprobe.patch @@ -0,0 +1,83 @@ +From 1e6fd6730bc923dbc510243b51f17eb93e2d670e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 15:10:09 +0200 +Subject: riscv: blacklist assembly symbols for kprobe +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Clément Léger + +[ Upstream commit 5014396af9bbac0f28d9afee7eae405206d01ee7 ] + +Adding kprobes on some assembly functions (mainly exception handling) +will result in crashes (either recursive trap or panic). To avoid such +errors, add ASM_NOKPROBE() macro which allow adding specific symbols +into the __kprobe_blacklist section and use to blacklist the following +symbols that showed to be problematic: +- handle_exception() +- ret_from_exception() +- handle_kernel_stack_overflow() + +Signed-off-by: Clément Léger +Reviewed-by: Charlie Jenkins +Link: https://lore.kernel.org/r/20231004131009.409193-1-cleger@rivosinc.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/asm.h | 10 ++++++++++ + arch/riscv/kernel/entry.S | 3 +++ + 2 files changed, 13 insertions(+) + +diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h +index bfb4c26f113c4..b5b84c6be01e1 100644 +--- a/arch/riscv/include/asm/asm.h ++++ b/arch/riscv/include/asm/asm.h +@@ -164,6 +164,16 @@ + REG_L x31, PT_T6(sp) + .endm + ++/* Annotate a function as being unsuitable for kprobes. */ ++#ifdef CONFIG_KPROBES ++#define ASM_NOKPROBE(name) \ ++ .pushsection "_kprobe_blacklist", "aw"; \ ++ RISCV_PTR name; \ ++ .popsection ++#else ++#define ASM_NOKPROBE(name) ++#endif ++ + #endif /* __ASSEMBLY__ */ + + #endif /* _ASM_RISCV_ASM_H */ +diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S +index 278d01d2911fd..ed7baf2cf7e87 100644 +--- a/arch/riscv/kernel/entry.S ++++ b/arch/riscv/kernel/entry.S +@@ -105,6 +105,7 @@ _save_context: + 1: + tail do_trap_unknown + SYM_CODE_END(handle_exception) ++ASM_NOKPROBE(handle_exception) + + /* + * The ret_from_exception must be called with interrupt disabled. Here is the +@@ -171,6 +172,7 @@ SYM_CODE_START_NOALIGN(ret_from_exception) + sret + #endif + SYM_CODE_END(ret_from_exception) ++ASM_NOKPROBE(ret_from_exception) + + #ifdef CONFIG_VMAP_STACK + SYM_CODE_START_LOCAL(handle_kernel_stack_overflow) +@@ -206,6 +208,7 @@ SYM_CODE_START_LOCAL(handle_kernel_stack_overflow) + move a0, sp + tail handle_bad_stack + SYM_CODE_END(handle_kernel_stack_overflow) ++ASM_NOKPROBE(handle_kernel_stack_overflow) + #endif + + SYM_CODE_START(ret_from_fork) +-- +2.43.0 + diff --git a/queue-6.6/rtc-nct3018y-fix-possible-null-dereference.patch b/queue-6.6/rtc-nct3018y-fix-possible-null-dereference.patch new file mode 100644 index 00000000000..0ec359e35ed --- /dev/null +++ b/queue-6.6/rtc-nct3018y-fix-possible-null-dereference.patch @@ -0,0 +1,51 @@ +From 89e3337d70ff7f3fa23bc1cfd08eeba8e135f4cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Feb 2024 23:21:27 +0100 +Subject: rtc: nct3018y: fix possible NULL dereference + +From: Alexandre Belloni + +[ Upstream commit babfeb9cbe7ebc657bd5b3e4f9fde79f560b6acc ] + +alarm_enable and alarm_flag are allowed to be NULL but will be dereferenced +later by the dev_dbg call. + +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202305180042.DEzW1pSd-lkp@intel.com/ +Link: https://lore.kernel.org/r/20240229222127.1878176-1-alexandre.belloni@bootlin.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/rtc/rtc-nct3018y.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c +index ed4e606be8e58..c4533c0f53896 100644 +--- a/drivers/rtc/rtc-nct3018y.c ++++ b/drivers/rtc/rtc-nct3018y.c +@@ -99,6 +99,8 @@ static int nct3018y_get_alarm_mode(struct i2c_client *client, unsigned char *ala + if (flags < 0) + return flags; + *alarm_enable = flags & NCT3018Y_BIT_AIE; ++ dev_dbg(&client->dev, "%s:alarm_enable:%x\n", __func__, *alarm_enable); ++ + } + + if (alarm_flag) { +@@ -107,11 +109,9 @@ static int nct3018y_get_alarm_mode(struct i2c_client *client, unsigned char *ala + if (flags < 0) + return flags; + *alarm_flag = flags & NCT3018Y_BIT_AF; ++ dev_dbg(&client->dev, "%s:alarm_flag:%x\n", __func__, *alarm_flag); + } + +- dev_dbg(&client->dev, "%s:alarm_enable:%x alarm_flag:%x\n", +- __func__, *alarm_enable, *alarm_flag); +- + return 0; + } + +-- +2.43.0 + diff --git a/queue-6.6/rxrpc-don-t-pick-values-out-of-the-wire-header-when-.patch b/queue-6.6/rxrpc-don-t-pick-values-out-of-the-wire-header-when-.patch new file mode 100644 index 00000000000..e8a41fceee5 --- /dev/null +++ b/queue-6.6/rxrpc-don-t-pick-values-out-of-the-wire-header-when-.patch @@ -0,0 +1,64 @@ +From 9de8eb0d7b4d57a279563a44ace103ebeb901f8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jan 2024 08:24:58 +0000 +Subject: rxrpc: Don't pick values out of the wire header when setting up + security + +From: David Howells + +[ Upstream commit a1c9af4d4467354132417c2d8db10d6e928a7f77 ] + +Don't pick values out of the wire header in rxkad when setting up DATA +packet security, but rather use other sources. This makes it easier to get +rid of txb->wire. + +Signed-off-by: David Howells +cc: Marc Dionne +cc: "David S. Miller" +cc: Eric Dumazet +cc: Jakub Kicinski +cc: Paolo Abeni +cc: linux-afs@lists.infradead.org +cc: netdev@vger.kernel.org +Signed-off-by: Sasha Levin +--- + net/rxrpc/rxkad.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c +index 6b32d61d4cdc4..ad6c57a9f27c7 100644 +--- a/net/rxrpc/rxkad.c ++++ b/net/rxrpc/rxkad.c +@@ -259,7 +259,7 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call, + + _enter(""); + +- check = txb->seq ^ ntohl(txb->wire.callNumber); ++ check = txb->seq ^ call->call_id; + hdr->data_size = htonl((u32)check << 16 | txb->len); + + txb->len += sizeof(struct rxkad_level1_hdr); +@@ -302,7 +302,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, + + _enter(""); + +- check = txb->seq ^ ntohl(txb->wire.callNumber); ++ check = txb->seq ^ call->call_id; + + rxkhdr->data_size = htonl(txb->len | (u32)check << 16); + rxkhdr->checksum = 0; +@@ -362,9 +362,9 @@ static int rxkad_secure_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb) + memcpy(&iv, call->conn->rxkad.csum_iv.x, sizeof(iv)); + + /* calculate the security checksum */ +- x = (ntohl(txb->wire.cid) & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT); ++ x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT); + x |= txb->seq & 0x3fffffff; +- crypto.buf[0] = txb->wire.callNumber; ++ crypto.buf[0] = htonl(call->call_id); + crypto.buf[1] = htonl(x); + + sg_init_one(&sg, crypto.buf, 8); +-- +2.43.0 + diff --git a/queue-6.6/s390-iucv-fix-receive-buffer-virtual-vs-physical-add.patch b/queue-6.6/s390-iucv-fix-receive-buffer-virtual-vs-physical-add.patch new file mode 100644 index 00000000000..14db43b758c --- /dev/null +++ b/queue-6.6/s390-iucv-fix-receive-buffer-virtual-vs-physical-add.patch @@ -0,0 +1,38 @@ +From 9e7e4033dc1936d93d46b9ea351ec331b140c036 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 13:13:26 +0100 +Subject: s390/iucv: fix receive buffer virtual vs physical address confusion + +From: Alexander Gordeev + +[ Upstream commit 4e8477aeb46dfe74e829c06ea588dd00ba20c8cc ] + +Fix IUCV_IPBUFLST-type buffers virtual vs physical address confusion. +This does not fix a bug since virtual and physical address spaces are +currently the same. + +Signed-off-by: Alexander Gordeev +Reviewed-by: Alexandra Winter +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + net/iucv/iucv.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c +index db41eb2d977f2..038e1ba9aec27 100644 +--- a/net/iucv/iucv.c ++++ b/net/iucv/iucv.c +@@ -1090,8 +1090,7 @@ static int iucv_message_receive_iprmdata(struct iucv_path *path, + size = (size < 8) ? size : 8; + for (array = buffer; size > 0; array++) { + copy = min_t(size_t, size, array->length); +- memcpy((u8 *)(addr_t) array->address, +- rmmsg, copy); ++ memcpy(phys_to_virt(array->address), rmmsg, copy); + rmmsg += copy; + size -= copy; + } +-- +2.43.0 + diff --git a/queue-6.6/scsi-lpfc-initialize-status-local-variable-in-lpfc_s.patch b/queue-6.6/scsi-lpfc-initialize-status-local-variable-in-lpfc_s.patch new file mode 100644 index 00000000000..d4d6ea17409 --- /dev/null +++ b/queue-6.6/scsi-lpfc-initialize-status-local-variable-in-lpfc_s.patch @@ -0,0 +1,41 @@ +From ccffda25d358b77aaff1be86507ed127fd83d6ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 10:50:56 -0800 +Subject: scsi: lpfc: Initialize status local variable in + lpfc_sli4_repost_sgl_list() + +From: Justin Tee + +[ Upstream commit 3d0f9342ae200aa1ddc4d6e7a573c6f8f068d994 ] + +A static code analyzer tool indicates that the local variable called status +in the lpfc_sli4_repost_sgl_list() routine could be used to print garbage +uninitialized values in the routine's log message. + +Fix by initializing to zero. + +Signed-off-by: Justin Tee +Link: https://lore.kernel.org/r/20240131185112.149731-2-justintee8345@gmail.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_sli.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 5af669b930193..9cd22588c8eb3 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -7577,7 +7577,7 @@ lpfc_sli4_repost_sgl_list(struct lpfc_hba *phba, + struct lpfc_sglq *sglq_entry = NULL; + struct lpfc_sglq *sglq_entry_next = NULL; + struct lpfc_sglq *sglq_entry_first = NULL; +- int status, total_cnt; ++ int status = 0, total_cnt; + int post_cnt = 0, num_posted = 0, block_cnt = 0; + int last_xritag = NO_XRI; + LIST_HEAD(prep_sgl_list); +-- +2.43.0 + diff --git a/queue-6.6/selftests-bpf-fix-a-few-tests-for-gcc-related-warnin.patch b/queue-6.6/selftests-bpf-fix-a-few-tests-for-gcc-related-warnin.patch new file mode 100644 index 00000000000..383bd38e555 --- /dev/null +++ b/queue-6.6/selftests-bpf-fix-a-few-tests-for-gcc-related-warnin.patch @@ -0,0 +1,278 @@ +From 535225176618cc094cde38bf2f949cd1faeaf368 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2024 19:38:50 +0100 +Subject: selftests/bpf: Fix a few tests for GCC related warnings. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cupertino Miranda + +[ Upstream commit 5ddafcc377f98778acc08f660dee6400aece6a62 ] + +This patch corrects a few warnings to allow selftests to compile for +GCC. + +-- progs/cpumask_failure.c -- + +progs/bpf_misc.h:136:22: error: ‘cpumask’ is used uninitialized +[-Werror=uninitialized] + 136 | #define __sink(expr) asm volatile("" : "+g"(expr)) + | ^~~ +progs/cpumask_failure.c:68:9: note: in expansion of macro ‘__sink’ + 68 | __sink(cpumask); + +The macro __sink(cpumask) with the '+' contraint modifier forces the +the compiler to expect a read and write from cpumask. GCC detects +that cpumask is never initialized and reports an error. +This patch removes the spurious non required definitions of cpumask. + +-- progs/dynptr_fail.c -- + +progs/dynptr_fail.c:1444:9: error: ‘ptr1’ may be used uninitialized +[-Werror=maybe-uninitialized] + 1444 | bpf_dynptr_clone(&ptr1, &ptr2); + +Many of the tests in the file are related to the detection of +uninitialized pointers by the verifier. GCC is able to detect possible +uninitialized values, and reports this as an error. +The patch initializes all of the previous uninitialized structs. + +-- progs/test_tunnel_kern.c -- + +progs/test_tunnel_kern.c:590:9: error: array subscript 1 is outside +array bounds of ‘struct geneve_opt[1]’ [-Werror=array-bounds=] + 590 | *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef); + | ^~~~~~~~~~~~~~~~~~~~~~~ +progs/test_tunnel_kern.c:575:27: note: at offset 4 into object ‘gopt’ of +size 4 + 575 | struct geneve_opt gopt; + +This tests accesses beyond the defined data for the struct geneve_opt +which contains as last field "u8 opt_data[0]" which clearly does not get +reserved space (in stack) in the function header. This pattern is +repeated in ip6geneve_set_tunnel and geneve_set_tunnel functions. +GCC is able to see this and emits a warning. +The patch introduces a local struct that allocates enough space to +safely allow the write to opt_data field. + +-- progs/jeq_infer_not_null_fail.c -- + +progs/jeq_infer_not_null_fail.c:21:40: error: array subscript ‘struct +bpf_map[0]’ is partly outside array bounds of ‘struct [1]’ +[-Werror=array-bounds=] + 21 | struct bpf_map *inner_map = map->inner_map_meta; + | ^~ +progs/jeq_infer_not_null_fail.c:14:3: note: object ‘m_hash’ of size 32 + 14 | } m_hash SEC(".maps"); + +This example defines m_hash in the context of the compilation unit and +casts it to struct bpf_map which is much smaller than the size of struct +bpf_map. It errors out in GCC when it attempts to access an element that +would be defined in struct bpf_map outsize of the defined limits for +m_hash. +This patch disables the warning through a GCC pragma. + +This changes were tested in bpf-next master selftests without any +regressions. + +Signed-off-by: Cupertino Miranda +Cc: jose.marchesi@oracle.com +Cc: david.faust@oracle.com +Cc: Yonghong Song +Cc: Eduard Zingerman +Cc: Andrii Nakryiko +Link: https://lore.kernel.org/r/20240510183850.286661-2-cupertino.miranda@oracle.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/progs/cpumask_failure.c | 3 -- + .../testing/selftests/bpf/progs/dynptr_fail.c | 12 ++--- + .../bpf/progs/jeq_infer_not_null_fail.c | 4 ++ + .../selftests/bpf/progs/test_tunnel_kern.c | 47 +++++++++++-------- + 4 files changed, 37 insertions(+), 29 deletions(-) + +diff --git a/tools/testing/selftests/bpf/progs/cpumask_failure.c b/tools/testing/selftests/bpf/progs/cpumask_failure.c +index a9bf6ea336cf6..a988d2823b528 100644 +--- a/tools/testing/selftests/bpf/progs/cpumask_failure.c ++++ b/tools/testing/selftests/bpf/progs/cpumask_failure.c +@@ -61,11 +61,8 @@ SEC("tp_btf/task_newtask") + __failure __msg("bpf_cpumask_set_cpu args#1 expected pointer to STRUCT bpf_cpumask") + int BPF_PROG(test_mutate_cpumask, struct task_struct *task, u64 clone_flags) + { +- struct bpf_cpumask *cpumask; +- + /* Can't set the CPU of a non-struct bpf_cpumask. */ + bpf_cpumask_set_cpu(0, (struct bpf_cpumask *)task->cpus_ptr); +- __sink(cpumask); + + return 0; + } +diff --git a/tools/testing/selftests/bpf/progs/dynptr_fail.c b/tools/testing/selftests/bpf/progs/dynptr_fail.c +index 7ce7e827d5f01..66a60bfb58672 100644 +--- a/tools/testing/selftests/bpf/progs/dynptr_fail.c ++++ b/tools/testing/selftests/bpf/progs/dynptr_fail.c +@@ -80,7 +80,7 @@ SEC("?raw_tp") + __failure __msg("Unreleased reference id=2") + int ringbuf_missing_release1(void *ctx) + { +- struct bpf_dynptr ptr; ++ struct bpf_dynptr ptr = {}; + + bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); + +@@ -1385,7 +1385,7 @@ SEC("?raw_tp") + __failure __msg("Expected an initialized dynptr as arg #1") + int dynptr_adjust_invalid(void *ctx) + { +- struct bpf_dynptr ptr; ++ struct bpf_dynptr ptr = {}; + + /* this should fail */ + bpf_dynptr_adjust(&ptr, 1, 2); +@@ -1398,7 +1398,7 @@ SEC("?raw_tp") + __failure __msg("Expected an initialized dynptr as arg #1") + int dynptr_is_null_invalid(void *ctx) + { +- struct bpf_dynptr ptr; ++ struct bpf_dynptr ptr = {}; + + /* this should fail */ + bpf_dynptr_is_null(&ptr); +@@ -1411,7 +1411,7 @@ SEC("?raw_tp") + __failure __msg("Expected an initialized dynptr as arg #1") + int dynptr_is_rdonly_invalid(void *ctx) + { +- struct bpf_dynptr ptr; ++ struct bpf_dynptr ptr = {}; + + /* this should fail */ + bpf_dynptr_is_rdonly(&ptr); +@@ -1424,7 +1424,7 @@ SEC("?raw_tp") + __failure __msg("Expected an initialized dynptr as arg #1") + int dynptr_size_invalid(void *ctx) + { +- struct bpf_dynptr ptr; ++ struct bpf_dynptr ptr = {}; + + /* this should fail */ + bpf_dynptr_size(&ptr); +@@ -1437,7 +1437,7 @@ SEC("?raw_tp") + __failure __msg("Expected an initialized dynptr as arg #1") + int clone_invalid1(void *ctx) + { +- struct bpf_dynptr ptr1; ++ struct bpf_dynptr ptr1 = {}; + struct bpf_dynptr ptr2; + + /* this should fail */ +diff --git a/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c b/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c +index f46965053acb2..4d619bea9c758 100644 +--- a/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c ++++ b/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c +@@ -4,6 +4,10 @@ + #include + #include "bpf_misc.h" + ++#ifndef __clang__ ++#pragma GCC diagnostic ignored "-Warray-bounds" ++#endif ++ + char _license[] SEC("license") = "GPL"; + + struct { +diff --git a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +index f66af753bbbb8..e68da33d7631d 100644 +--- a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c ++++ b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +@@ -597,12 +597,18 @@ int ip6vxlan_get_tunnel_src(struct __sk_buff *skb) + return TC_ACT_OK; + } + ++struct local_geneve_opt { ++ struct geneve_opt gopt; ++ int data; ++}; ++ + SEC("tc") + int geneve_set_tunnel(struct __sk_buff *skb) + { + int ret; + struct bpf_tunnel_key key; +- struct geneve_opt gopt; ++ struct local_geneve_opt local_gopt; ++ struct geneve_opt *gopt = (struct geneve_opt *) &local_gopt; + + __builtin_memset(&key, 0x0, sizeof(key)); + key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ +@@ -610,14 +616,14 @@ int geneve_set_tunnel(struct __sk_buff *skb) + key.tunnel_tos = 0; + key.tunnel_ttl = 64; + +- __builtin_memset(&gopt, 0x0, sizeof(gopt)); +- gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */ +- gopt.type = 0x08; +- gopt.r1 = 0; +- gopt.r2 = 0; +- gopt.r3 = 0; +- gopt.length = 2; /* 4-byte multiple */ +- *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef); ++ __builtin_memset(gopt, 0x0, sizeof(local_gopt)); ++ gopt->opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */ ++ gopt->type = 0x08; ++ gopt->r1 = 0; ++ gopt->r2 = 0; ++ gopt->r3 = 0; ++ gopt->length = 2; /* 4-byte multiple */ ++ *(int *) &gopt->opt_data = bpf_htonl(0xdeadbeef); + + ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), + BPF_F_ZERO_CSUM_TX); +@@ -626,7 +632,7 @@ int geneve_set_tunnel(struct __sk_buff *skb) + return TC_ACT_SHOT; + } + +- ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt)); ++ ret = bpf_skb_set_tunnel_opt(skb, gopt, sizeof(local_gopt)); + if (ret < 0) { + log_err(ret); + return TC_ACT_SHOT; +@@ -661,7 +667,8 @@ SEC("tc") + int ip6geneve_set_tunnel(struct __sk_buff *skb) + { + struct bpf_tunnel_key key; +- struct geneve_opt gopt; ++ struct local_geneve_opt local_gopt; ++ struct geneve_opt *gopt = (struct geneve_opt *) &local_gopt; + int ret; + + __builtin_memset(&key, 0x0, sizeof(key)); +@@ -677,16 +684,16 @@ int ip6geneve_set_tunnel(struct __sk_buff *skb) + return TC_ACT_SHOT; + } + +- __builtin_memset(&gopt, 0x0, sizeof(gopt)); +- gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */ +- gopt.type = 0x08; +- gopt.r1 = 0; +- gopt.r2 = 0; +- gopt.r3 = 0; +- gopt.length = 2; /* 4-byte multiple */ +- *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef); ++ __builtin_memset(gopt, 0x0, sizeof(local_gopt)); ++ gopt->opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */ ++ gopt->type = 0x08; ++ gopt->r1 = 0; ++ gopt->r2 = 0; ++ gopt->r3 = 0; ++ gopt->length = 2; /* 4-byte multiple */ ++ *(int *) &gopt->opt_data = bpf_htonl(0xfeedbeef); + +- ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt)); ++ ret = bpf_skb_set_tunnel_opt(skb, gopt, sizeof(gopt)); + if (ret < 0) { + log_err(ret); + return TC_ACT_SHOT; +-- +2.43.0 + diff --git a/queue-6.6/serial-pch-don-t-disable-interrupts-while-acquiring-.patch b/queue-6.6/serial-pch-don-t-disable-interrupts-while-acquiring-.patch new file mode 100644 index 00000000000..e8a2daa2038 --- /dev/null +++ b/queue-6.6/serial-pch-don-t-disable-interrupts-while-acquiring-.patch @@ -0,0 +1,52 @@ +From a6a0bf518d1180c78afa538fec3bf7559e36eb01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Mar 2024 22:45:28 +0100 +Subject: serial: pch: Don't disable interrupts while acquiring lock in ISR. + +From: Sebastian Andrzej Siewior + +[ Upstream commit f8ff23ebce8c305383c8070e1ea3b08a69eb1e8d ] + +The interrupt service routine is always invoked with disabled +interrupts. + +Remove the _irqsave() from the locking functions in the interrupts +service routine/ pch_uart_interrupt(). + +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20240301215246.891055-16-bigeasy@linutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/pch_uart.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c +index cc83b772b7ca9..8b56cbdc893d1 100644 +--- a/drivers/tty/serial/pch_uart.c ++++ b/drivers/tty/serial/pch_uart.c +@@ -1019,11 +1019,10 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) + u8 lsr; + int ret = 0; + unsigned char iid; +- unsigned long flags; + int next = 1; + u8 msr; + +- spin_lock_irqsave(&priv->lock, flags); ++ spin_lock(&priv->lock); + handled = 0; + while (next) { + iid = pch_uart_hal_get_iid(priv); +@@ -1083,7 +1082,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) + handled |= (unsigned int)ret; + } + +- spin_unlock_irqrestore(&priv->lock, flags); ++ spin_unlock(&priv->lock); + return IRQ_RETVAL(handled); + } + +-- +2.43.0 + diff --git a/queue-6.6/series b/queue-6.6/series index c1d31c7abe1..ed74732a205 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -137,3 +137,86 @@ cpu-smt-enable-smt-only-if-a-core-is-online.patch powerpc-topology-check-if-a-core-is-online.patch arm64-fix-kasan-random-tag-seed-initialization.patch block-fix-lockdep-warning-in-blk_mq_mark_tag_wait.patch +drm-msm-reduce-fallout-of-fence-signaling-vs-reclaim.patch +memory-tegra-skip-sid-programming-if-sid-registers-a.patch +powerpc-xics-check-return-value-of-kasprintf-in-icp_.patch +asoc-sof-ipc4-check-return-value-of-snd_sof_ipc_msg_.patch +hwmon-pc87360-bounds-check-data-innr-usage.patch +powerpc-pseries-papr-sysparm-validate-buffer-object-.patch +ionic-prevent-pci-disable-of-already-disabled-device.patch +ionic-no-fw-read-when-pci-reset-failed.patch +drm-rockchip-vop2-clear-afbc-en-and-transform-bit-fo.patch +evm-don-t-copy-up-security.evm-xattr.patch +bluetooth-hci_conn-check-non-null-function-before-ca.patch +gfs2-refcounting-fix-in-gfs2_thaw_super.patch +edac-skx_common-filter-out-the-invalid-address.patch +drm-amdgpu-gfx11-need-acquire-mutex-before-access-cp.patch +nvmet-trace-avoid-dereferencing-pointer-too-early.patch +ext4-do-not-trim-the-group-with-corrupted-block-bitm.patch +btrfs-zlib-fix-and-simplify-the-inline-extent-decomp.patch +afs-fix-__afs_break_callback-afs_drop_open_mmap-race.patch +fuse-fix-uaf-in-rcu-pathwalks.patch +wifi-ath12k-add-missing-qmi_txn_cancel-calls.patch +quota-remove-bug_on-from-dqget.patch +riscv-blacklist-assembly-symbols-for-kprobe.patch +kernfs-fix-false-positive-warn-nr_mmapped-in-kernfs_.patch +media-pci-cx23885-check-cx23885_vdev_init-return.patch +fs-binfmt_elf_efpic-don-t-use-missing-interpreter-s-.patch +scsi-lpfc-initialize-status-local-variable-in-lpfc_s.patch +media-drivers-media-dvb-core-copy-user-arrays-safely.patch +wifi-iwlwifi-mvm-avoid-garbage-ipn.patch +net-sun3_82586-avoid-reading-past-buffer-in-debug-ou.patch +drm-lima-set-gp-bus_stop-bit-before-hard-reset.patch +gpio-sysfs-extend-the-critical-section-for-unregiste.patch +hrtimer-select-housekeeping-cpu-during-migration.patch +virtiofs-forbid-newlines-in-tags.patch +accel-habanalabs-fix-debugfs-files-permissions.patch +clocksource-drivers-arm_global_timer-guard-against-d.patch +tick-move-got_idle_tick-away-from-common-flags.patch +netlink-hold-nlk-cb_mutex-longer-in-__netlink_dump_s.patch +md-clean-up-invalid-bug_on-in-md_ioctl.patch +x86-increase-brk-randomness-entropy-for-64-bit-syste.patch +memory-stm32-fmc2-ebi-check-regmap_read-return-value.patch +parisc-use-irq_enter_rcu-to-fix-warning-at-kernel-co.patch +rxrpc-don-t-pick-values-out-of-the-wire-header-when-.patch +f2fs-stop-checkpoint-when-get-a-out-of-bounds-segmen.patch +serial-pch-don-t-disable-interrupts-while-acquiring-.patch +powerpc-boot-handle-allocation-failure-in-simple_rea.patch +powerpc-boot-only-free-if-realloc-succeeds.patch +btrfs-delayed-inode-drop-pointless-bug_on-in-__btrfs.patch +btrfs-defrag-change-bug_on-to-assertion-in-btrfs_def.patch +btrfs-change-bug_on-to-assertion-when-checking-for-d.patch +btrfs-tests-allocate-dummy-fs_info-and-root-in-test_.patch +btrfs-push-errors-up-from-add_async_extent.patch +btrfs-handle-invalid-root-reference-found-in-may_des.patch +btrfs-send-handle-unexpected-data-in-header-buffer-i.patch +btrfs-send-handle-unexpected-inode-in-header-process.patch +btrfs-change-bug_on-to-assertion-in-tree_move_down.patch +btrfs-delete-pointless-bug_on-check-on-quota-root-in.patch +f2fs-fix-to-do-sanity-check-in-update_sit_entry.patch +usb-gadget-fsl-increase-size-of-name-buffer-for-endp.patch +nvme-clear-caller-pointer-on-identify-failure.patch +bluetooth-bnep-fix-out-of-bound-access.patch +firmware-cirrus-cs_dsp-initialize-debugfs_root-to-in.patch +rtc-nct3018y-fix-possible-null-dereference.patch +net-hns3-add-checking-for-vf-id-of-mailbox.patch +nvmet-tcp-do-not-continue-for-invalid-icreq.patch +nfs-avoid-infinite-loop-in-pnfs_update_layout.patch +openrisc-call-setup_memory-earlier-in-the-init-seque.patch +s390-iucv-fix-receive-buffer-virtual-vs-physical-add.patch +irqchip-renesas-rzg2l-do-not-set-tien-and-tint-sourc.patch +clocksource-make-watchdog-and-suspend-timing-multipl.patch +platform-x86-lg-laptop-fix-s-null-argument-warning.patch +usb-dwc3-core-skip-setting-event-buffers-for-host-on.patch +irqchip-gic-v3-its-remove-bug_on-in-its_vpe_irq_doma.patch +ext4-set-the-type-of-max_zeroout-to-unsigned-int-to-.patch +nvmet-rdma-fix-possible-bad-dereference-when-freeing.patch +selftests-bpf-fix-a-few-tests-for-gcc-related-warnin.patch +revert-bpf-sockmap-prevent-lock-inversion-deadlock-i.patch +nvme-use-srcu-for-iterating-namespace-list.patch +drm-amdgpu-fix-dereference-null-return-value-for-the.patch +hrtimer-prevent-queuing-of-hrtimer-without-a-functio.patch +ionic-use-pci_is_enabled-not-open-code.patch +ionic-check-cmd_regs-before-copying-in-or-out.patch +edac-skx_common-allow-decoding-of-sgx-addresses.patch +nvme-fix-namespace-removal-list.patch diff --git a/queue-6.6/tick-move-got_idle_tick-away-from-common-flags.patch b/queue-6.6/tick-move-got_idle_tick-away-from-common-flags.patch new file mode 100644 index 00000000000..788212a1e70 --- /dev/null +++ b/queue-6.6/tick-move-got_idle_tick-away-from-common-flags.patch @@ -0,0 +1,60 @@ +From f842d78ffd0ec0941e4113afec3e3e0bcb60035c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Feb 2024 23:55:03 +0100 +Subject: tick: Move got_idle_tick away from common flags + +From: Frederic Weisbecker + +[ Upstream commit 3ce74f1a8566dbbc9774f85fb0ce781fe290fd32 ] + +tick_nohz_idle_got_tick() is called by cpuidle_reflect() within the idle +loop with interrupts enabled. This function modifies the struct +tick_sched's bitfield "got_idle_tick". However this bitfield is stored +within the same mask as other bitfields that can be modified from +interrupts. + +Fortunately so far it looks like the only race that can happen is while +writing ->got_idle_tick to 0, an interrupt fires and writes the +->idle_active field to 0. It's then possible that the interrupted write +to ->got_idle_tick writes back the old value of ->idle_active back to 1. + +However if that happens, the worst possible outcome is that the time +spent between that interrupt and the upcoming call to +tick_nohz_idle_exit() is accounted as idle, which is negligible quantity. + +Still all the bitfield writes within this struct tick_sched's shadow +mask should be IRQ-safe. Therefore move this bitfield out to its own +storage to avoid further suprises. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Reviewed-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20240225225508.11587-12-frederic@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/time/tick-sched.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h +index 5ed5a9d41d5a7..03a586e12cf89 100644 +--- a/kernel/time/tick-sched.h ++++ b/kernel/time/tick-sched.h +@@ -61,7 +61,6 @@ struct tick_sched { + unsigned int tick_stopped : 1; + unsigned int idle_active : 1; + unsigned int do_timer_last : 1; +- unsigned int got_idle_tick : 1; + + /* Tick handling: jiffies stall check */ + unsigned int stalled_jiffies; +@@ -73,6 +72,7 @@ struct tick_sched { + ktime_t next_tick; + unsigned long idle_jiffies; + ktime_t idle_waketime; ++ unsigned int got_idle_tick; + + /* Idle entry */ + seqcount_t idle_sleeptime_seq; +-- +2.43.0 + diff --git a/queue-6.6/usb-dwc3-core-skip-setting-event-buffers-for-host-on.patch b/queue-6.6/usb-dwc3-core-skip-setting-event-buffers-for-host-on.patch new file mode 100644 index 00000000000..74ee6008217 --- /dev/null +++ b/queue-6.6/usb-dwc3-core-skip-setting-event-buffers-for-host-on.patch @@ -0,0 +1,71 @@ +From f110419b5488ea7ea8d04973733bb06f85852e06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 20 Apr 2024 10:18:55 +0530 +Subject: usb: dwc3: core: Skip setting event buffers for host only controllers + +From: Krishna Kurapati + +[ Upstream commit 89d7f962994604a3e3d480832788d06179abefc5 ] + +On some SoC's like SA8295P where the tertiary controller is host-only +capable, GEVTADDRHI/LO, GEVTSIZ, GEVTCOUNT registers are not accessible. +Trying to access them leads to a crash. + +For DRD/Peripheral supported controllers, event buffer setup is done +again in gadget_pullup. Skip setup or cleanup of event buffers if +controller is host-only capable. + +Suggested-by: Johan Hovold +Signed-off-by: Krishna Kurapati +Acked-by: Thinh Nguyen +Reviewed-by: Johan Hovold +Reviewed-by: Bjorn Andersson +Tested-by: Johan Hovold +Link: https://lore.kernel.org/r/20240420044901.884098-4-quic_kriskura@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/core.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 674467b7638ea..5ce276cb39d0d 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -506,6 +506,13 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) + static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length) + { + struct dwc3_event_buffer *evt; ++ unsigned int hw_mode; ++ ++ hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); ++ if (hw_mode == DWC3_GHWPARAMS0_MODE_HOST) { ++ dwc->ev_buf = NULL; ++ return 0; ++ } + + evt = dwc3_alloc_one_event_buffer(dwc, length); + if (IS_ERR(evt)) { +@@ -527,6 +534,9 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) + { + struct dwc3_event_buffer *evt; + ++ if (!dwc->ev_buf) ++ return 0; ++ + evt = dwc->ev_buf; + evt->lpos = 0; + dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), +@@ -544,6 +554,9 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) + { + struct dwc3_event_buffer *evt; + ++ if (!dwc->ev_buf) ++ return; ++ + evt = dwc->ev_buf; + + evt->lpos = 0; +-- +2.43.0 + diff --git a/queue-6.6/usb-gadget-fsl-increase-size-of-name-buffer-for-endp.patch b/queue-6.6/usb-gadget-fsl-increase-size-of-name-buffer-for-endp.patch new file mode 100644 index 00000000000..6d89ada8828 --- /dev/null +++ b/queue-6.6/usb-gadget-fsl-increase-size-of-name-buffer-for-endp.patch @@ -0,0 +1,40 @@ +From 12fc7f94a675ab34f604c12062eb902ddf5fa61b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Feb 2024 18:33:16 +0100 +Subject: usb: gadget: fsl: Increase size of name buffer for endpoints +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 87850f6cc20911e35eafcbc1d56b0d649ae9162d ] + +This fixes a W=1 warning about sprintf writing up to 16 bytes into a +buffer of size 14. There is no practical relevance because there are not +more than 32 endpoints. + +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/6754df25c56aae04f8110594fad2cd2452b1862a.1708709120.git.u.kleine-koenig@pengutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/udc/fsl_udc_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c +index ee5705d336e3d..10a82527626eb 100644 +--- a/drivers/usb/gadget/udc/fsl_udc_core.c ++++ b/drivers/usb/gadget/udc/fsl_udc_core.c +@@ -2486,7 +2486,7 @@ static int fsl_udc_probe(struct platform_device *pdev) + /* setup the udc->eps[] for non-control endpoints and link + * to gadget.ep_list */ + for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) { +- char name[14]; ++ char name[16]; + + sprintf(name, "ep%dout", i); + struct_ep_setup(udc_controller, i * 2, name, 1); +-- +2.43.0 + diff --git a/queue-6.6/virtiofs-forbid-newlines-in-tags.patch b/queue-6.6/virtiofs-forbid-newlines-in-tags.patch new file mode 100644 index 00000000000..10437476034 --- /dev/null +++ b/queue-6.6/virtiofs-forbid-newlines-in-tags.patch @@ -0,0 +1,44 @@ +From c92f5d70727b06fd0f1eb7ed58786ea5b0e7bad8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Feb 2024 19:11:47 -0500 +Subject: virtiofs: forbid newlines in tags + +From: Stefan Hajnoczi + +[ Upstream commit 40488cc16f7ea0d193a4e248f0d809c25cc377db ] + +Newlines in virtiofs tags are awkward for users and potential vectors +for string injection attacks. + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Vivek Goyal +Signed-off-by: Miklos Szeredi +Signed-off-by: Sasha Levin +--- + fs/fuse/virtio_fs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c +index 5f1be1da92ce9..d84dacbdce2c9 100644 +--- a/fs/fuse/virtio_fs.c ++++ b/fs/fuse/virtio_fs.c +@@ -323,6 +323,16 @@ static int virtio_fs_read_tag(struct virtio_device *vdev, struct virtio_fs *fs) + return -ENOMEM; + memcpy(fs->tag, tag_buf, len); + fs->tag[len] = '\0'; ++ ++ /* While the VIRTIO specification allows any character, newlines are ++ * awkward on mount(8) command-lines and cause problems in the sysfs ++ * "tag" attr and uevent TAG= properties. Forbid them. ++ */ ++ if (strchr(fs->tag, '\n')) { ++ dev_dbg(&vdev->dev, "refusing virtiofs tag with newline character\n"); ++ return -EINVAL; ++ } ++ + return 0; + } + +-- +2.43.0 + diff --git a/queue-6.6/wifi-ath12k-add-missing-qmi_txn_cancel-calls.patch b/queue-6.6/wifi-ath12k-add-missing-qmi_txn_cancel-calls.patch new file mode 100644 index 00000000000..7223306e9a8 --- /dev/null +++ b/queue-6.6/wifi-ath12k-add-missing-qmi_txn_cancel-calls.patch @@ -0,0 +1,91 @@ +From 6430977f4dd817f0e94a9b40c02dbccaf9b57b74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Jan 2024 10:05:31 -0800 +Subject: wifi: ath12k: Add missing qmi_txn_cancel() calls + +From: Jeff Johnson + +[ Upstream commit 2e82b5f09a97f1b98b885470c81c1248bec103af ] + +Per the QMI documentation "A client calling qmi_txn_init() must call +either qmi_txn_wait() or qmi_txn_cancel() to free up the allocated +resources." + +Unfortunately, in most of the ath12k messaging functions, when +qmi_send_request() fails, the function returns without performing the +necessary cleanup. So update those functions to call qmi_txn_cancel() +when qmi_send_request() fails. + +No functional changes, compile tested only. + +Signed-off-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240111-qmi-cleanup-v2-2-53343af953d5@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/qmi.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c +index e68accbc837f4..f1379a5e60cdd 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.c ++++ b/drivers/net/wireless/ath/ath12k/qmi.c +@@ -1977,6 +1977,7 @@ static int ath12k_qmi_host_cap_send(struct ath12k_base *ab) + QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_host_cap_req_msg_v01_ei, &req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret); + goto out; + } +@@ -2040,6 +2041,7 @@ static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab) + QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_ind_register_req_msg_v01_ei, req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "Failed to send indication register request, err = %d\n", + ret); + goto out; +@@ -2114,6 +2116,7 @@ static int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab) + QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_respond_mem_req_msg_v01_ei, req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n", + ret); + goto out; +@@ -2228,6 +2231,7 @@ static int ath12k_qmi_request_target_cap(struct ath12k_base *ab) + QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_cap_req_msg_v01_ei, &req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n", + ret); + goto out; +@@ -2567,6 +2571,7 @@ static int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) + QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN, + qmi_wlanfw_m3_info_req_msg_v01_ei, &req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n", + ret); + goto out; +@@ -2613,6 +2618,7 @@ static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab, + QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n", + mode, ret); + goto out; +@@ -2704,6 +2710,7 @@ static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab) + QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN, + qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req); + if (ret < 0) { ++ qmi_txn_cancel(&txn); + ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n", + ret); + goto out; +-- +2.43.0 + diff --git a/queue-6.6/wifi-iwlwifi-mvm-avoid-garbage-ipn.patch b/queue-6.6/wifi-iwlwifi-mvm-avoid-garbage-ipn.patch new file mode 100644 index 00000000000..c90a412bd47 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-mvm-avoid-garbage-ipn.patch @@ -0,0 +1,46 @@ +From 065097b079e419b675bbddffb2e5f1552ec0a0cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Feb 2024 21:21:13 +0200 +Subject: wifi: iwlwifi: mvm: avoid garbage iPN + +From: Shaul Triebitz + +[ Upstream commit 0c1c91604f3e3fc41f4d77dcfc3753860a9a32c9 ] + +After waking from D3, we set the iPN given by the firmware. +For some reason, CIPHER_SUITE_AES_CMAC was missed. +That caused copying garbage to the iPN - causing false replays. + +(since 'seq' is on the stack, and the iPN from the firmware +was not copied into it, it contains garbage which later is +copied to the iPN key). + +Signed-off-by: Shaul Triebitz +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240205211151.2be5b35be30f.I99db8700d01092d22a6d76f1fc1bd5916c9df784@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +index 9c89f0dd69c86..08d1fab7f53c3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +@@ -1849,9 +1849,12 @@ iwl_mvm_d3_set_igtk_bigtk_ipn(const struct iwl_multicast_key_data *key, + memcpy(seq->aes_gmac.pn, key->ipn, sizeof(seq->aes_gmac.pn)); + break; + case WLAN_CIPHER_SUITE_BIP_CMAC_256: ++ case WLAN_CIPHER_SUITE_AES_CMAC: + BUILD_BUG_ON(sizeof(seq->aes_cmac.pn) != sizeof(key->ipn)); + memcpy(seq->aes_cmac.pn, key->ipn, sizeof(seq->aes_cmac.pn)); + break; ++ default: ++ WARN_ON(1); + } + } + +-- +2.43.0 + diff --git a/queue-6.6/x86-increase-brk-randomness-entropy-for-64-bit-syste.patch b/queue-6.6/x86-increase-brk-randomness-entropy-for-64-bit-syste.patch new file mode 100644 index 00000000000..6330a78bc52 --- /dev/null +++ b/queue-6.6/x86-increase-brk-randomness-entropy-for-64-bit-syste.patch @@ -0,0 +1,47 @@ +From 14d3625c3effc0070c7f802c15da622eac9fd169 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 22:25:43 -0800 +Subject: x86: Increase brk randomness entropy for 64-bit systems + +From: Kees Cook + +[ Upstream commit 44c76825d6eefee9eb7ce06c38e1a6632ac7eb7d ] + +In commit c1d171a00294 ("x86: randomize brk"), arch_randomize_brk() was +defined to use a 32MB range (13 bits of entropy), but was never increased +when moving to 64-bit. The default arch_randomize_brk() uses 32MB for +32-bit tasks, and 1GB (18 bits of entropy) for 64-bit tasks. + +Update x86_64 to match the entropy used by arm64 and other 64-bit +architectures. + +Reported-by: y0un9n132@gmail.com +Signed-off-by: Kees Cook +Signed-off-by: Thomas Gleixner +Acked-by: Jiri Kosina +Closes: https://lore.kernel.org/linux-hardening/CA+2EKTVLvc8hDZc+2Yhwmus=dzOUG5E4gV7ayCbu0MPJTZzWkw@mail.gmail.com/ +Link: https://lore.kernel.org/r/20240217062545.1631668-1-keescook@chromium.org +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/process.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index b6f4e8399fca2..5351f293f770b 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -1030,7 +1030,10 @@ unsigned long arch_align_stack(unsigned long sp) + + unsigned long arch_randomize_brk(struct mm_struct *mm) + { +- return randomize_page(mm->brk, 0x02000000); ++ if (mmap_is_ia32()) ++ return randomize_page(mm->brk, SZ_32M); ++ ++ return randomize_page(mm->brk, SZ_1G); + } + + /* +-- +2.43.0 +