From: Sasha Levin Date: Mon, 20 Nov 2023 14:23:26 +0000 (-0500) Subject: Fixes for 6.5 X-Git-Tag: v4.14.331~154 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5ff2f8debaf5a354c39e5e610eab98513a07e76f;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.5 Signed-off-by: Sasha Levin --- diff --git a/queue-6.5/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch b/queue-6.5/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch new file mode 100644 index 00000000000..c3c717300b4 --- /dev/null +++ b/queue-6.5/9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch @@ -0,0 +1,94 @@ +From 71246038d34935e693b26f12d94db10cab990ed3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 19:34:43 +0900 +Subject: 9p/trans_fd: Annotate data-racy writes to file::f_flags + +From: Marco Elver + +[ Upstream commit 355f074609dbf3042900ea9d30fcd2b0c323a365 ] + +syzbot reported: + + | BUG: KCSAN: data-race in p9_fd_create / p9_fd_create + | + | read-write to 0xffff888130fb3d48 of 4 bytes by task 15599 on cpu 0: + | p9_fd_open net/9p/trans_fd.c:842 [inline] + | p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092 + | p9_client_create+0x595/0xa70 net/9p/client.c:1010 + | v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410 + | v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123 + | legacy_get_tree+0x74/0xd0 fs/fs_context.c:611 + | vfs_get_tree+0x51/0x190 fs/super.c:1519 + | do_new_mount+0x203/0x660 fs/namespace.c:3335 + | path_mount+0x496/0xb30 fs/namespace.c:3662 + | do_mount fs/namespace.c:3675 [inline] + | __do_sys_mount fs/namespace.c:3884 [inline] + | [...] + | + | read-write to 0xffff888130fb3d48 of 4 bytes by task 15563 on cpu 1: + | p9_fd_open net/9p/trans_fd.c:842 [inline] + | p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092 + | p9_client_create+0x595/0xa70 net/9p/client.c:1010 + | v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410 + | v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123 + | legacy_get_tree+0x74/0xd0 fs/fs_context.c:611 + | vfs_get_tree+0x51/0x190 fs/super.c:1519 + | do_new_mount+0x203/0x660 fs/namespace.c:3335 + | path_mount+0x496/0xb30 fs/namespace.c:3662 + | do_mount fs/namespace.c:3675 [inline] + | __do_sys_mount fs/namespace.c:3884 [inline] + | [...] + | + | value changed: 0x00008002 -> 0x00008802 + +Within p9_fd_open(), O_NONBLOCK is added to f_flags of the read and +write files. This may happen concurrently if e.g. mounting process +modifies the fd in another thread. + +Mark the plain read-modify-writes as intentional data-races, with the +assumption that the result of executing the accesses concurrently will +always result in the same result despite the accesses themselves not +being atomic. + +Reported-by: syzbot+e441aeeb422763cc5511@syzkaller.appspotmail.com +Signed-off-by: Marco Elver +Link: https://lore.kernel.org/r/ZO38mqkS0TYUlpFp@elver.google.com +Signed-off-by: Dominique Martinet +Message-ID: <20231025103445.1248103-1-asmadeus@codewreck.org> +Signed-off-by: Sasha Levin +--- + net/9p/trans_fd.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c +index 00b684616e8d9..9374790f17ce4 100644 +--- a/net/9p/trans_fd.c ++++ b/net/9p/trans_fd.c +@@ -832,14 +832,21 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd) + goto out_free_ts; + if (!(ts->rd->f_mode & FMODE_READ)) + goto out_put_rd; +- /* prevent workers from hanging on IO when fd is a pipe */ +- ts->rd->f_flags |= O_NONBLOCK; ++ /* Prevent workers from hanging on IO when fd is a pipe. ++ * It's technically possible for userspace or concurrent mounts to ++ * modify this flag concurrently, which will likely result in a ++ * broken filesystem. However, just having bad flags here should ++ * not crash the kernel or cause any other sort of bug, so mark this ++ * particular data race as intentional so that tooling (like KCSAN) ++ * can allow it and detect further problems. ++ */ ++ data_race(ts->rd->f_flags |= O_NONBLOCK); + ts->wr = fget(wfd); + if (!ts->wr) + goto out_put_rd; + if (!(ts->wr->f_mode & FMODE_WRITE)) + goto out_put_wr; +- ts->wr->f_flags |= O_NONBLOCK; ++ data_race(ts->wr->f_flags |= O_NONBLOCK); + + client->trans = ts; + client->status = Connected; +-- +2.42.0 + diff --git a/queue-6.5/9p-v9fs_listxattr-fix-s-null-argument-warning.patch b/queue-6.5/9p-v9fs_listxattr-fix-s-null-argument-warning.patch new file mode 100644 index 00000000000..56af152fa69 --- /dev/null +++ b/queue-6.5/9p-v9fs_listxattr-fix-s-null-argument-warning.patch @@ -0,0 +1,77 @@ +From 5f14e12498777f9201e91c9fbdb5efd64ff213b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 19:34:44 +0900 +Subject: 9p: v9fs_listxattr: fix %s null argument warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dominique Martinet + +[ Upstream commit 9b5c6281838fc84683dd99b47302d81fce399918 ] + +W=1 warns about null argument to kprintf: +In file included from fs/9p/xattr.c:12: +In function ‘v9fs_xattr_get’, + inlined from ‘v9fs_listxattr’ at fs/9p/xattr.c:142:9: +include/net/9p/9p.h:55:2: error: ‘%s’ directive argument is null +[-Werror=format-overflow=] + 55 | _p9_debug(level, __func__, fmt, ##__VA_ARGS__) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use an empty string instead of : + - this is ok 9p-wise because p9pdu_vwritef serializes a null string +and an empty string the same way (one '0' word for length) + - since this degrades the print statements, add new single quotes for +xattr's name delimter (Old: "file = (null)", new: "file = ''") + +Link: https://lore.kernel.org/r/20231008060138.517057-1-suhui@nfschina.com +Suggested-by: Su Hui +Signed-off-by: Dominique Martinet +Acked-by: Christian Schoenebeck +Message-ID: <20231025103445.1248103-2-asmadeus@codewreck.org> +Signed-off-by: Sasha Levin +--- + fs/9p/xattr.c | 5 +++-- + net/9p/client.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c +index e00cf8109b3f3..3c4572ef3a488 100644 +--- a/fs/9p/xattr.c ++++ b/fs/9p/xattr.c +@@ -68,7 +68,7 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name, + struct p9_fid *fid; + int ret; + +- p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n", ++ p9_debug(P9_DEBUG_VFS, "name = '%s' value_len = %zu\n", + name, buffer_size); + fid = v9fs_fid_lookup(dentry); + if (IS_ERR(fid)) +@@ -139,7 +139,8 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name, + + ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) + { +- return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); ++ /* Txattrwalk with an empty string lists xattrs instead */ ++ return v9fs_xattr_get(dentry, "", buffer, buffer_size); + } + + static int v9fs_xattr_handler_get(const struct xattr_handler *handler, +diff --git a/net/9p/client.c b/net/9p/client.c +index b0e7cb7e1a54a..e265a0ca6bddd 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -1981,7 +1981,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, + goto error; + } + p9_debug(P9_DEBUG_9P, +- ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n", ++ ">>> TXATTRWALK file_fid %d, attr_fid %d name '%s'\n", + file_fid->fid, attr_fid->fid, attr_name); + + req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds", +-- +2.42.0 + diff --git a/queue-6.5/acpi-apei-fix-aer-info-corruption-when-error-status-.patch b/queue-6.5/acpi-apei-fix-aer-info-corruption-when-error-status-.patch new file mode 100644 index 00000000000..9f7c766c0fa --- /dev/null +++ b/queue-6.5/acpi-apei-fix-aer-info-corruption-when-error-status-.patch @@ -0,0 +1,137 @@ +From 208eee44f46b455f8631301c4ab5adfb4e2b5b29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 02:03:36 +0800 +Subject: ACPI: APEI: Fix AER info corruption when error status data has + multiple sections + +From: Shiju Jose + +[ Upstream commit e2abc47a5a1a9f641e7cacdca643fdd40729bf6e ] + +ghes_handle_aer() passes AER data to the PCI core for logging and +recovery by calling aer_recover_queue() with a pointer to struct +aer_capability_regs. + +The problem was that aer_recover_queue() queues the pointer directly +without copying the aer_capability_regs data. The pointer was to +the ghes->estatus buffer, which could be reused before +aer_recover_work_func() reads the data. + +To avoid this problem, allocate a new aer_capability_regs structure +from the ghes_estatus_pool, copy the AER data from the ghes->estatus +buffer into it, pass a pointer to the new struct to +aer_recover_queue(), and free it after aer_recover_work_func() has +processed it. + +Reported-by: Bjorn Helgaas +Acked-by: Bjorn Helgaas +Signed-off-by: Shiju Jose +[ rjw: Subject edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/apei/ghes.c | 23 ++++++++++++++++++++++- + drivers/pci/pcie/aer.c | 10 ++++++++++ + include/acpi/ghes.h | 4 ++++ + 3 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index ef59d6ea16da0..63ad0541db381 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -209,6 +209,20 @@ int ghes_estatus_pool_init(unsigned int num_ghes) + return -ENOMEM; + } + ++/** ++ * ghes_estatus_pool_region_free - free previously allocated memory ++ * from the ghes_estatus_pool. ++ * @addr: address of memory to free. ++ * @size: size of memory to free. ++ * ++ * Returns none. ++ */ ++void ghes_estatus_pool_region_free(unsigned long addr, u32 size) ++{ ++ gen_pool_free(ghes_estatus_pool, addr, size); ++} ++EXPORT_SYMBOL_GPL(ghes_estatus_pool_region_free); ++ + static int map_gen_v2(struct ghes *ghes) + { + return apei_map_generic_address(&ghes->generic_v2->read_ack_register); +@@ -564,6 +578,7 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) + pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { + unsigned int devfn; + int aer_severity; ++ u8 *aer_info; + + devfn = PCI_DEVFN(pcie_err->device_id.device, + pcie_err->device_id.function); +@@ -577,11 +592,17 @@ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) + if (gdata->flags & CPER_SEC_RESET) + aer_severity = AER_FATAL; + ++ aer_info = (void *)gen_pool_alloc(ghes_estatus_pool, ++ sizeof(struct aer_capability_regs)); ++ if (!aer_info) ++ return; ++ memcpy(aer_info, pcie_err->aer_info, sizeof(struct aer_capability_regs)); ++ + aer_recover_queue(pcie_err->device_id.segment, + pcie_err->device_id.bus, + devfn, aer_severity, + (struct aer_capability_regs *) +- pcie_err->aer_info); ++ aer_info); + } + #endif + } +diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c +index f6c24ded134cd..67025ee2b7454 100644 +--- a/drivers/pci/pcie/aer.c ++++ b/drivers/pci/pcie/aer.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + + #include "../pci.h" +@@ -1010,6 +1011,15 @@ static void aer_recover_work_func(struct work_struct *work) + continue; + } + cper_print_aer(pdev, entry.severity, entry.regs); ++ /* ++ * Memory for aer_capability_regs(entry.regs) is being allocated from the ++ * ghes_estatus_pool to protect it from overwriting when multiple sections ++ * are present in the error status. Thus free the same after processing ++ * the data. ++ */ ++ ghes_estatus_pool_region_free((unsigned long)entry.regs, ++ sizeof(struct aer_capability_regs)); ++ + if (entry.severity == AER_NONFATAL) + pcie_do_recovery(pdev, pci_channel_io_normal, + aer_root_reset); +diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h +index 3c8bba9f1114a..be1dd4c1a9174 100644 +--- a/include/acpi/ghes.h ++++ b/include/acpi/ghes.h +@@ -73,8 +73,12 @@ int ghes_register_vendor_record_notifier(struct notifier_block *nb); + void ghes_unregister_vendor_record_notifier(struct notifier_block *nb); + + struct list_head *ghes_get_devices(void); ++ ++void ghes_estatus_pool_region_free(unsigned long addr, u32 size); + #else + static inline struct list_head *ghes_get_devices(void) { return NULL; } ++ ++static inline void ghes_estatus_pool_region_free(unsigned long addr, u32 size) { return; } + #endif + + int ghes_estatus_pool_init(unsigned int num_ghes); +-- +2.42.0 + diff --git a/queue-6.5/acpi-ec-add-quirk-for-hp-250-g7-notebook-pc.patch b/queue-6.5/acpi-ec-add-quirk-for-hp-250-g7-notebook-pc.patch new file mode 100644 index 00000000000..7cd09662b1a --- /dev/null +++ b/queue-6.5/acpi-ec-add-quirk-for-hp-250-g7-notebook-pc.patch @@ -0,0 +1,46 @@ +From 05b1d56bf30b4a715d6d85796fa84ecca0b91a8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 09:13:36 -0500 +Subject: ACPI: EC: Add quirk for HP 250 G7 Notebook PC + +From: Jonathan Denose + +[ Upstream commit 891ddc03e2f4395e24795596e032f57d5ab37fe7 ] + +Add GPE quirk entry for HP 250 G7 Notebook PC. + +This change allows the lid switch to be identified as the lid switch +and not a keyboard button. With the lid switch properly identified, the +device triggers suspend correctly on lid close. + +Signed-off-by: Jonathan Denose +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/ec.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index c95d0edb0be9e..a59c11df73754 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -1924,6 +1924,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-dk1xxx"), + }, + }, ++ { ++ /* ++ * HP 250 G7 Notebook PC ++ */ ++ .callback = ec_honor_dsdt_gpe, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "HP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP 250 G7 Notebook PC"), ++ }, ++ }, + { + /* + * Samsung hardware +-- +2.42.0 + diff --git a/queue-6.5/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch b/queue-6.5/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch new file mode 100644 index 00000000000..d9059db100b --- /dev/null +++ b/queue-6.5/af_unix-fix-use-after-free-in-unix_stream_read_actor.patch @@ -0,0 +1,219 @@ +From 623f2d142124036453b4ad9035ffaec0d81f5ba5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 13:49:38 +0000 +Subject: af_unix: fix use-after-free in unix_stream_read_actor() + +From: Eric Dumazet + +[ Upstream commit 4b7b492615cf3017190f55444f7016812b66611d ] + +syzbot reported the following crash [1] + +After releasing unix socket lock, u->oob_skb can be changed +by another thread. We must temporarily increase skb refcount +to make sure this other thread will not free the skb under us. + +[1] + +BUG: KASAN: slab-use-after-free in unix_stream_read_actor+0xa7/0xc0 net/unix/af_unix.c:2866 +Read of size 4 at addr ffff88801f3b9cc4 by task syz-executor107/5297 + +CPU: 1 PID: 5297 Comm: syz-executor107 Not tainted 6.6.0-syzkaller-15910-gb8e3a87a627b #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023 +Call Trace: + +__dump_stack lib/dump_stack.c:88 [inline] +dump_stack_lvl+0xd9/0x1b0 lib/dump_stack.c:106 +print_address_description mm/kasan/report.c:364 [inline] +print_report+0xc4/0x620 mm/kasan/report.c:475 +kasan_report+0xda/0x110 mm/kasan/report.c:588 +unix_stream_read_actor+0xa7/0xc0 net/unix/af_unix.c:2866 +unix_stream_recv_urg net/unix/af_unix.c:2587 [inline] +unix_stream_read_generic+0x19a5/0x2480 net/unix/af_unix.c:2666 +unix_stream_recvmsg+0x189/0x1b0 net/unix/af_unix.c:2903 +sock_recvmsg_nosec net/socket.c:1044 [inline] +sock_recvmsg+0xe2/0x170 net/socket.c:1066 +____sys_recvmsg+0x21f/0x5c0 net/socket.c:2803 +___sys_recvmsg+0x115/0x1a0 net/socket.c:2845 +__sys_recvmsg+0x114/0x1e0 net/socket.c:2875 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b +RIP: 0033:0x7fc67492c559 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007fc6748ab228 EFLAGS: 00000246 ORIG_RAX: 000000000000002f +RAX: ffffffffffffffda RBX: 000000000000001c RCX: 00007fc67492c559 +RDX: 0000000040010083 RSI: 0000000020000140 RDI: 0000000000000004 +RBP: 00007fc6749b6348 R08: 00007fc6748ab6c0 R09: 00007fc6748ab6c0 +R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc6749b6340 +R13: 00007fc6749b634c R14: 00007ffe9fac52a0 R15: 00007ffe9fac5388 + + +Allocated by task 5295: +kasan_save_stack+0x33/0x50 mm/kasan/common.c:45 +kasan_set_track+0x25/0x30 mm/kasan/common.c:52 +__kasan_slab_alloc+0x81/0x90 mm/kasan/common.c:328 +kasan_slab_alloc include/linux/kasan.h:188 [inline] +slab_post_alloc_hook mm/slab.h:763 [inline] +slab_alloc_node mm/slub.c:3478 [inline] +kmem_cache_alloc_node+0x180/0x3c0 mm/slub.c:3523 +__alloc_skb+0x287/0x330 net/core/skbuff.c:641 +alloc_skb include/linux/skbuff.h:1286 [inline] +alloc_skb_with_frags+0xe4/0x710 net/core/skbuff.c:6331 +sock_alloc_send_pskb+0x7e4/0x970 net/core/sock.c:2780 +sock_alloc_send_skb include/net/sock.h:1884 [inline] +queue_oob net/unix/af_unix.c:2147 [inline] +unix_stream_sendmsg+0xb5f/0x10a0 net/unix/af_unix.c:2301 +sock_sendmsg_nosec net/socket.c:730 [inline] +__sock_sendmsg+0xd5/0x180 net/socket.c:745 +____sys_sendmsg+0x6ac/0x940 net/socket.c:2584 +___sys_sendmsg+0x135/0x1d0 net/socket.c:2638 +__sys_sendmsg+0x117/0x1e0 net/socket.c:2667 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Freed by task 5295: +kasan_save_stack+0x33/0x50 mm/kasan/common.c:45 +kasan_set_track+0x25/0x30 mm/kasan/common.c:52 +kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:522 +____kasan_slab_free mm/kasan/common.c:236 [inline] +____kasan_slab_free+0x15b/0x1b0 mm/kasan/common.c:200 +kasan_slab_free include/linux/kasan.h:164 [inline] +slab_free_hook mm/slub.c:1800 [inline] +slab_free_freelist_hook+0x114/0x1e0 mm/slub.c:1826 +slab_free mm/slub.c:3809 [inline] +kmem_cache_free+0xf8/0x340 mm/slub.c:3831 +kfree_skbmem+0xef/0x1b0 net/core/skbuff.c:1015 +__kfree_skb net/core/skbuff.c:1073 [inline] +consume_skb net/core/skbuff.c:1288 [inline] +consume_skb+0xdf/0x170 net/core/skbuff.c:1282 +queue_oob net/unix/af_unix.c:2178 [inline] +unix_stream_sendmsg+0xd49/0x10a0 net/unix/af_unix.c:2301 +sock_sendmsg_nosec net/socket.c:730 [inline] +__sock_sendmsg+0xd5/0x180 net/socket.c:745 +____sys_sendmsg+0x6ac/0x940 net/socket.c:2584 +___sys_sendmsg+0x135/0x1d0 net/socket.c:2638 +__sys_sendmsg+0x117/0x1e0 net/socket.c:2667 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b + +The buggy address belongs to the object at ffff88801f3b9c80 +which belongs to the cache skbuff_head_cache of size 240 +The buggy address is located 68 bytes inside of +freed 240-byte region [ffff88801f3b9c80, ffff88801f3b9d70) + +The buggy address belongs to the physical page: +page:ffffea00007cee40 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1f3b9 +flags: 0xfff00000000800(slab|node=0|zone=1|lastcpupid=0x7ff) +page_type: 0xffffffff() +raw: 00fff00000000800 ffff888142a60640 dead000000000122 0000000000000000 +raw: 0000000000000000 00000000000c000c 00000001ffffffff 0000000000000000 +page dumped because: kasan: bad access detected +page_owner tracks the page as allocated +page last allocated via order 0, migratetype Unmovable, gfp_mask 0x12cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY), pid 5299, tgid 5283 (syz-executor107), ts 103803840339, free_ts 103600093431 +set_page_owner include/linux/page_owner.h:31 [inline] +post_alloc_hook+0x2cf/0x340 mm/page_alloc.c:1537 +prep_new_page mm/page_alloc.c:1544 [inline] +get_page_from_freelist+0xa25/0x36c0 mm/page_alloc.c:3312 +__alloc_pages+0x1d0/0x4a0 mm/page_alloc.c:4568 +alloc_pages_mpol+0x258/0x5f0 mm/mempolicy.c:2133 +alloc_slab_page mm/slub.c:1870 [inline] +allocate_slab+0x251/0x380 mm/slub.c:2017 +new_slab mm/slub.c:2070 [inline] +___slab_alloc+0x8c7/0x1580 mm/slub.c:3223 +__slab_alloc.constprop.0+0x56/0xa0 mm/slub.c:3322 +__slab_alloc_node mm/slub.c:3375 [inline] +slab_alloc_node mm/slub.c:3468 [inline] +kmem_cache_alloc_node+0x132/0x3c0 mm/slub.c:3523 +__alloc_skb+0x287/0x330 net/core/skbuff.c:641 +alloc_skb include/linux/skbuff.h:1286 [inline] +alloc_skb_with_frags+0xe4/0x710 net/core/skbuff.c:6331 +sock_alloc_send_pskb+0x7e4/0x970 net/core/sock.c:2780 +sock_alloc_send_skb include/net/sock.h:1884 [inline] +queue_oob net/unix/af_unix.c:2147 [inline] +unix_stream_sendmsg+0xb5f/0x10a0 net/unix/af_unix.c:2301 +sock_sendmsg_nosec net/socket.c:730 [inline] +__sock_sendmsg+0xd5/0x180 net/socket.c:745 +____sys_sendmsg+0x6ac/0x940 net/socket.c:2584 +___sys_sendmsg+0x135/0x1d0 net/socket.c:2638 +__sys_sendmsg+0x117/0x1e0 net/socket.c:2667 +page last free stack trace: +reset_page_owner include/linux/page_owner.h:24 [inline] +free_pages_prepare mm/page_alloc.c:1137 [inline] +free_unref_page_prepare+0x4f8/0xa90 mm/page_alloc.c:2347 +free_unref_page+0x33/0x3b0 mm/page_alloc.c:2487 +__unfreeze_partials+0x21d/0x240 mm/slub.c:2655 +qlink_free mm/kasan/quarantine.c:168 [inline] +qlist_free_all+0x6a/0x170 mm/kasan/quarantine.c:187 +kasan_quarantine_reduce+0x18e/0x1d0 mm/kasan/quarantine.c:294 +__kasan_slab_alloc+0x65/0x90 mm/kasan/common.c:305 +kasan_slab_alloc include/linux/kasan.h:188 [inline] +slab_post_alloc_hook mm/slab.h:763 [inline] +slab_alloc_node mm/slub.c:3478 [inline] +slab_alloc mm/slub.c:3486 [inline] +__kmem_cache_alloc_lru mm/slub.c:3493 [inline] +kmem_cache_alloc+0x15d/0x380 mm/slub.c:3502 +vm_area_dup+0x21/0x2f0 kernel/fork.c:500 +__split_vma+0x17d/0x1070 mm/mmap.c:2365 +split_vma mm/mmap.c:2437 [inline] +vma_modify+0x25d/0x450 mm/mmap.c:2472 +vma_modify_flags include/linux/mm.h:3271 [inline] +mprotect_fixup+0x228/0xc80 mm/mprotect.c:635 +do_mprotect_pkey+0x852/0xd60 mm/mprotect.c:809 +__do_sys_mprotect mm/mprotect.c:830 [inline] +__se_sys_mprotect mm/mprotect.c:827 [inline] +__x64_sys_mprotect+0x78/0xb0 mm/mprotect.c:827 +do_syscall_x64 arch/x86/entry/common.c:51 [inline] +do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:82 +entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Memory state around the buggy address: +ffff88801f3b9b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +ffff88801f3b9c00: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc +>ffff88801f3b9c80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb +^ +ffff88801f3b9d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc +ffff88801f3b9d80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb + +Fixes: 876c14ad014d ("af_unix: fix holding spinlock in oob handling") +Reported-and-tested-by: syzbot+7a2d546fa43e49315ed3@syzkaller.appspotmail.com +Signed-off-by: Eric Dumazet +Cc: Rao Shoaib +Reviewed-by: Rao shoaib +Link: https://lore.kernel.org/r/20231113134938.168151-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 3e8a04a136688..3e6eeacb13aec 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2553,15 +2553,16 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state) + + if (!(state->flags & MSG_PEEK)) + WRITE_ONCE(u->oob_skb, NULL); +- ++ else ++ skb_get(oob_skb); + unix_state_unlock(sk); + + chunk = state->recv_actor(oob_skb, 0, chunk, state); + +- if (!(state->flags & MSG_PEEK)) { ++ if (!(state->flags & MSG_PEEK)) + UNIXCB(oob_skb).consumed += 1; +- kfree_skb(oob_skb); +- } ++ ++ consume_skb(oob_skb); + + mutex_unlock(&u->iolock); + +-- +2.42.0 + diff --git a/queue-6.5/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch b/queue-6.5/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch new file mode 100644 index 00000000000..c66ea8926c0 --- /dev/null +++ b/queue-6.5/alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch @@ -0,0 +1,42 @@ +From ecd6c8ede68b97e7fcb6250c9887130612b20d34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 12:28:55 +0200 +Subject: ALSA: hda: Fix possible null-ptr-deref when assigning a stream + +From: Cezary Rojewski + +[ Upstream commit f93dc90c2e8ed664985e366aa6459ac83cdab236 ] + +While AudioDSP drivers assign streams exclusively of HOST or LINK type, +nothing blocks a user to attempt to assign a COUPLED stream. As +supplied substream instance may be a stub, what is the case when +code-loading, such scenario ends with null-ptr-deref. + +Signed-off-by: Cezary Rojewski +Link: https://lore.kernel.org/r/20231006102857.749143-2-cezary.rojewski@intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/hdac_stream.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c +index 2633a4bb1d85d..214a0680524b0 100644 +--- a/sound/hda/hdac_stream.c ++++ b/sound/hda/hdac_stream.c +@@ -354,8 +354,10 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus, + struct hdac_stream *res = NULL; + + /* make a non-zero unique key for the substream */ +- int key = (substream->pcm->device << 16) | (substream->number << 2) | +- (substream->stream + 1); ++ int key = (substream->number << 2) | (substream->stream + 1); ++ ++ if (substream->pcm) ++ key |= (substream->pcm->device << 16); + + spin_lock_irq(&bus->reg_lock); + list_for_each_entry(azx_dev, &bus->stream_list, list) { +-- +2.42.0 + diff --git a/queue-6.5/alsa-hda-realtek-add-quirk-for-asus-ux7602zm.patch b/queue-6.5/alsa-hda-realtek-add-quirk-for-asus-ux7602zm.patch new file mode 100644 index 00000000000..831e117856b --- /dev/null +++ b/queue-6.5/alsa-hda-realtek-add-quirk-for-asus-ux7602zm.patch @@ -0,0 +1,39 @@ +From 65ecf1019ed032517b72c4709df91d7b2426e657 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Nov 2023 16:01:52 -0500 +Subject: ALSA: hda/realtek: Add quirk for ASUS UX7602ZM + +From: Alex Spataru + +[ Upstream commit 26fd31ef9c02a5e91cdb8eea127b056bd7cf0b3b ] + +Enables the SPI-connected CSC35L41 audio amplifier for this +laptop model. + +As of BIOS version 303 it's still necessary to +modify the ACPI table to add the related _DSD properties: +https://github.com/alex-spataru/asus_zenbook_ux7602zm_sound/ + +Signed-off-by: Alex Spataru +Link: https://lore.kernel.org/r/DS7PR07MB7621BB5BB14F5473D181624CE3A4A@DS7PR07MB7621.namprd07.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 7f1d79f450a2a..fe9a29f358792 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9798,6 +9798,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), ++ SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), + SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), +-- +2.42.0 + diff --git a/queue-6.5/alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch b/queue-6.5/alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch new file mode 100644 index 00000000000..4a10393c8d1 --- /dev/null +++ b/queue-6.5/alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch @@ -0,0 +1,195 @@ +From 89fb36f7da74eddb9bdbd9e2ff925bfb31bfd8ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 03:02:16 +0930 +Subject: ALSA: scarlett2: Move USB IDs out from device_info struct + +From: Geoffrey D. Bennett + +[ Upstream commit d98cc489029dba4d99714c2e8ec4f5ba249f6851 ] + +By moving the USB IDs from the device_info struct into +scarlett2_devices[], that will allow for devices with different +USB IDs to share the same device_info. + +Tested-by: Philippe Perrot +Signed-off-by: Geoffrey D. Bennett +Link: https://lore.kernel.org/r/8263368e8d49e6fcebc709817bd82ab79b404468.1694705811.git.g@b4.vu +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/mixer_scarlett_gen2.c | 63 ++++++++++++--------------------- + 1 file changed, 23 insertions(+), 40 deletions(-) + +diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c +index 9d11bb08667e7..48f5c9b9790dc 100644 +--- a/sound/usb/mixer_scarlett_gen2.c ++++ b/sound/usb/mixer_scarlett_gen2.c +@@ -317,8 +317,6 @@ struct scarlett2_mux_entry { + }; + + struct scarlett2_device_info { +- u32 usb_id; /* USB device identifier */ +- + /* Gen 3 devices have an internal MSD mode switch that needs + * to be disabled in order to access the full functionality of + * the device. +@@ -440,8 +438,6 @@ struct scarlett2_data { + /*** Model-specific data ***/ + + static const struct scarlett2_device_info s6i6_gen2_info = { +- .usb_id = USB_ID(0x1235, 0x8203), +- + .config_set = SCARLETT2_CONFIG_SET_GEN_2, + .level_input_count = 2, + .pad_input_count = 2, +@@ -486,8 +482,6 @@ static const struct scarlett2_device_info s6i6_gen2_info = { + }; + + static const struct scarlett2_device_info s18i8_gen2_info = { +- .usb_id = USB_ID(0x1235, 0x8204), +- + .config_set = SCARLETT2_CONFIG_SET_GEN_2, + .level_input_count = 2, + .pad_input_count = 4, +@@ -535,8 +529,6 @@ static const struct scarlett2_device_info s18i8_gen2_info = { + }; + + static const struct scarlett2_device_info s18i20_gen2_info = { +- .usb_id = USB_ID(0x1235, 0x8201), +- + .config_set = SCARLETT2_CONFIG_SET_GEN_2, + .line_out_hw_vol = 1, + +@@ -589,8 +581,6 @@ static const struct scarlett2_device_info s18i20_gen2_info = { + }; + + static const struct scarlett2_device_info solo_gen3_info = { +- .usb_id = USB_ID(0x1235, 0x8211), +- + .has_msd_mode = 1, + .config_set = SCARLETT2_CONFIG_SET_NO_MIXER, + .level_input_count = 1, +@@ -602,8 +592,6 @@ static const struct scarlett2_device_info solo_gen3_info = { + }; + + static const struct scarlett2_device_info s2i2_gen3_info = { +- .usb_id = USB_ID(0x1235, 0x8210), +- + .has_msd_mode = 1, + .config_set = SCARLETT2_CONFIG_SET_NO_MIXER, + .level_input_count = 2, +@@ -614,8 +602,6 @@ static const struct scarlett2_device_info s2i2_gen3_info = { + }; + + static const struct scarlett2_device_info s4i4_gen3_info = { +- .usb_id = USB_ID(0x1235, 0x8212), +- + .has_msd_mode = 1, + .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .level_input_count = 2, +@@ -660,8 +646,6 @@ static const struct scarlett2_device_info s4i4_gen3_info = { + }; + + static const struct scarlett2_device_info s8i6_gen3_info = { +- .usb_id = USB_ID(0x1235, 0x8213), +- + .has_msd_mode = 1, + .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .level_input_count = 2, +@@ -713,8 +697,6 @@ static const struct scarlett2_device_info s8i6_gen3_info = { + }; + + static const struct scarlett2_device_info s18i8_gen3_info = { +- .usb_id = USB_ID(0x1235, 0x8214), +- + .has_msd_mode = 1, + .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .line_out_hw_vol = 1, +@@ -783,8 +765,6 @@ static const struct scarlett2_device_info s18i8_gen3_info = { + }; + + static const struct scarlett2_device_info s18i20_gen3_info = { +- .usb_id = USB_ID(0x1235, 0x8215), +- + .has_msd_mode = 1, + .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .line_out_hw_vol = 1, +@@ -848,8 +828,6 @@ static const struct scarlett2_device_info s18i20_gen3_info = { + }; + + static const struct scarlett2_device_info clarett_8pre_info = { +- .usb_id = USB_ID(0x1235, 0x820c), +- + .config_set = SCARLETT2_CONFIG_SET_CLARETT, + .line_out_hw_vol = 1, + .level_input_count = 2, +@@ -902,25 +880,30 @@ static const struct scarlett2_device_info clarett_8pre_info = { + } }, + }; + +-static const struct scarlett2_device_info *scarlett2_devices[] = { ++struct scarlett2_device_entry { ++ const u32 usb_id; /* USB device identifier */ ++ const struct scarlett2_device_info *info; ++}; ++ ++static const struct scarlett2_device_entry scarlett2_devices[] = { + /* Supported Gen 2 devices */ +- &s6i6_gen2_info, +- &s18i8_gen2_info, +- &s18i20_gen2_info, ++ { USB_ID(0x1235, 0x8203), &s6i6_gen2_info }, ++ { USB_ID(0x1235, 0x8204), &s18i8_gen2_info }, ++ { USB_ID(0x1235, 0x8201), &s18i20_gen2_info }, + + /* Supported Gen 3 devices */ +- &solo_gen3_info, +- &s2i2_gen3_info, +- &s4i4_gen3_info, +- &s8i6_gen3_info, +- &s18i8_gen3_info, +- &s18i20_gen3_info, ++ { USB_ID(0x1235, 0x8211), &solo_gen3_info }, ++ { USB_ID(0x1235, 0x8210), &s2i2_gen3_info }, ++ { USB_ID(0x1235, 0x8212), &s4i4_gen3_info }, ++ { USB_ID(0x1235, 0x8213), &s8i6_gen3_info }, ++ { USB_ID(0x1235, 0x8214), &s18i8_gen3_info }, ++ { USB_ID(0x1235, 0x8215), &s18i20_gen3_info }, + + /* Supported Clarett+ devices */ +- &clarett_8pre_info, ++ { USB_ID(0x1235, 0x820c), &clarett_8pre_info }, + + /* End of list */ +- NULL ++ { 0, NULL }, + }; + + /* get the starting port index number for a given port type/direction */ +@@ -4072,17 +4055,17 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer) + + static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer) + { +- const struct scarlett2_device_info **info = scarlett2_devices; ++ const struct scarlett2_device_entry *entry = scarlett2_devices; + int err; + +- /* Find device in scarlett2_devices */ +- while (*info && (*info)->usb_id != mixer->chip->usb_id) +- info++; +- if (!*info) ++ /* Find entry in scarlett2_devices */ ++ while (entry->usb_id && entry->usb_id != mixer->chip->usb_id) ++ entry++; ++ if (!entry->usb_id) + return -EINVAL; + + /* Initialise private data */ +- err = scarlett2_init_private(mixer, *info); ++ err = scarlett2_init_private(mixer, entry->info); + if (err < 0) + return err; + +-- +2.42.0 + diff --git a/queue-6.5/arm-9320-1-fix-stack-depot-irq-stack-filter.patch b/queue-6.5/arm-9320-1-fix-stack-depot-irq-stack-filter.patch new file mode 100644 index 00000000000..c7e54366a4f --- /dev/null +++ b/queue-6.5/arm-9320-1-fix-stack-depot-irq-stack-filter.patch @@ -0,0 +1,45 @@ +From f6d3df48bf96785b54be3059c9fb96e8fd820c86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 08:45:21 +0100 +Subject: ARM: 9320/1: fix stack depot IRQ stack filter + +From: Vincent Whitchurch + +[ Upstream commit b0150014878c32197cfa66e3e2f79e57f66babc0 ] + +Place IRQ handlers such as gic_handle_irq() in the irqentry section even +if FUNCTION_GRAPH_TRACER is not enabled. Without this, the stack +depot's filter_irq_stacks() does not correctly filter out IRQ stacks in +those configurations, which hampers deduplication and eventually leads +to "Stack depot reached limit capacity" splats with KASAN. + +A similar fix was done for arm64 in commit f6794950f0e5ba37e3bbed +("arm64: set __exception_irq_entry with __irq_entry as a default"). + +Link: https://lore.kernel.org/r/20230803-arm-irqentry-v1-1-8aad8e260b1c@axis.com + +Signed-off-by: Vincent Whitchurch +Signed-off-by: Russell King (Oracle) +Signed-off-by: Sasha Levin +--- + arch/arm/include/asm/exception.h | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h +index 58e039a851af0..3c82975d46db3 100644 +--- a/arch/arm/include/asm/exception.h ++++ b/arch/arm/include/asm/exception.h +@@ -10,10 +10,6 @@ + + #include + +-#ifdef CONFIG_FUNCTION_GRAPH_TRACER + #define __exception_irq_entry __irq_entry +-#else +-#define __exception_irq_entry +-#endif + + #endif /* __ASM_ARM_EXCEPTION_H */ +-- +2.42.0 + diff --git a/queue-6.5/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch b/queue-6.5/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch new file mode 100644 index 00000000000..b3db07e1194 --- /dev/null +++ b/queue-6.5/arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch @@ -0,0 +1,94 @@ +From f47c5ec4c91cfe8ade49ed596e95b478a741ca8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 18:10:15 +0300 +Subject: arm64: dts: ls208xa: use a pseudo-bus to constrain usb dma size + +From: Laurentiu Tudor + +[ Upstream commit b39d5016456871a88f5cd141914a5043591b46f3 ] + +Wrap the usb controllers in an intermediate simple-bus and use it to +constrain the dma address size of these usb controllers to the 40b +that they generate toward the interconnect. This is required because +the SoC uses 48b address sizes and this mismatch would lead to smmu +context faults [1] because the usb generates 40b addresses while the +smmu page tables are populated with 48b wide addresses. + +[1] +xhci-hcd xhci-hcd.0.auto: xHCI Host Controller +xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1 +xhci-hcd xhci-hcd.0.auto: hcc params 0x0220f66d hci version 0x100 quirks 0x0000000002000010 +xhci-hcd xhci-hcd.0.auto: irq 108, io mem 0x03100000 +xhci-hcd xhci-hcd.0.auto: xHCI Host Controller +xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2 +xhci-hcd xhci-hcd.0.auto: Host supports USB 3.0 SuperSpeed +arm-smmu 5000000.iommu: Unhandled context fault: fsr=0x402, iova=0xffffffb000, fsynr=0x0, cbfrsynra=0xc01, cb=3 + +Signed-off-by: Laurentiu Tudor +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 46 +++++++++++-------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +index d2f5345d05600..717288bbdb8b6 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +@@ -1186,26 +1186,34 @@ + dma-coherent; + }; + +- usb0: usb@3100000 { +- status = "disabled"; +- compatible = "snps,dwc3"; +- reg = <0x0 0x3100000 0x0 0x10000>; +- interrupts = <0 80 0x4>; /* Level high type */ +- dr_mode = "host"; +- snps,quirk-frame-length-adjustment = <0x20>; +- snps,dis_rxdet_inp3_quirk; +- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; +- }; ++ bus: bus { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ compatible = "simple-bus"; ++ ranges; ++ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; ++ ++ usb0: usb@3100000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0x3100000 0x0 0x10000>; ++ interrupts = <0 80 0x4>; /* Level high type */ ++ dr_mode = "host"; ++ snps,quirk-frame-length-adjustment = <0x20>; ++ snps,dis_rxdet_inp3_quirk; ++ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; ++ status = "disabled"; ++ }; + +- usb1: usb@3110000 { +- status = "disabled"; +- compatible = "snps,dwc3"; +- reg = <0x0 0x3110000 0x0 0x10000>; +- interrupts = <0 81 0x4>; /* Level high type */ +- dr_mode = "host"; +- snps,quirk-frame-length-adjustment = <0x20>; +- snps,dis_rxdet_inp3_quirk; +- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; ++ usb1: usb@3110000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0x3110000 0x0 0x10000>; ++ interrupts = <0 81 0x4>; /* Level high type */ ++ dr_mode = "host"; ++ snps,quirk-frame-length-adjustment = <0x20>; ++ snps,dis_rxdet_inp3_quirk; ++ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; ++ status = "disabled"; ++ }; + }; + + ccn@4000000 { +-- +2.42.0 + diff --git a/queue-6.5/asoc-intel-soc-acpi-cht-add-lenovo-yoga-tab-3-pro-yt.patch b/queue-6.5/asoc-intel-soc-acpi-cht-add-lenovo-yoga-tab-3-pro-yt.patch new file mode 100644 index 00000000000..d0e6317b8cc --- /dev/null +++ b/queue-6.5/asoc-intel-soc-acpi-cht-add-lenovo-yoga-tab-3-pro-yt.patch @@ -0,0 +1,90 @@ +From 968486dab8e9c14fb05d44fb5f10c45b6f478076 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Oct 2023 23:15:28 +0200 +Subject: ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Tab 3 Pro YT3-X90 quirk + +From: Hans de Goede + +[ Upstream commit 2cb54788393134d8174ee594002baae3ce52c61e ] + +The Lenovo Yoga Tab 3 Pro YT3-X90 x86 tablet, which ships with Android with +a custom kernel as factory OS, does not list the used WM5102 codec inside +its DSDT. + +Workaround this with a new snd_soc_acpi_intel_baytrail_machines[] entry +which matches on the SST id instead of the codec id like nocodec does, +combined with using a machine_quirk callback which returns NULL on +other machines to skip the new entry on other machines. + +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20231021211534.114991-1-hdegoede@redhat.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + .../intel/common/soc-acpi-intel-cht-match.c | 43 +++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c +index cdcbf04b8832f..5e2ec60e2954b 100644 +--- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c ++++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c +@@ -75,6 +75,39 @@ static struct snd_soc_acpi_mach *cht_ess8316_quirk(void *arg) + return arg; + } + ++/* ++ * The Lenovo Yoga Tab 3 Pro YT3-X90, with Android factory OS has a buggy DSDT ++ * with the coded not being listed at all. ++ */ ++static const struct dmi_system_id lenovo_yoga_tab3_x90[] = { ++ { ++ /* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), ++ }, ++ }, ++ { } ++}; ++ ++static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { ++ .id = "10WM5102", ++ .drv_name = "bytcr_wm5102", ++ .fw_filename = "intel/fw_sst_22a8.bin", ++ .board = "bytcr_wm5102", ++ .sof_tplg_filename = "sof-cht-wm5102.tplg", ++}; ++ ++static struct snd_soc_acpi_mach *lenovo_yt3_x90_quirk(void *arg) ++{ ++ if (dmi_check_system(lenovo_yoga_tab3_x90)) ++ return &cht_lenovo_yoga_tab3_x90_mach; ++ ++ /* Skip wildcard match snd_soc_acpi_intel_cherrytrail_machines[] entry */ ++ return NULL; ++} ++ + static const struct snd_soc_acpi_codecs rt5640_comp_ids = { + .num_codecs = 2, + .codecs = { "10EC5640", "10EC3276" }, +@@ -175,6 +208,16 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { + .drv_name = "sof_pcm512x", + .sof_tplg_filename = "sof-cht-src-50khz-pcm512x.tplg", + }, ++ /* ++ * Special case for the Lenovo Yoga Tab 3 Pro YT3-X90 where the DSDT ++ * misses the codec. Match on the SST id instead, lenovo_yt3_x90_quirk() ++ * will return a YT3 specific mach or NULL when called on other hw, ++ * skipping this entry. ++ */ ++ { ++ .id = "808622A8", ++ .machine_quirk = lenovo_yt3_x90_quirk, ++ }, + + #if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) + /* +-- +2.42.0 + diff --git a/queue-6.5/asoc-mediatek-mt8188-mt6359-support-dynamic-pinctrl.patch b/queue-6.5/asoc-mediatek-mt8188-mt6359-support-dynamic-pinctrl.patch new file mode 100644 index 00000000000..2f0a76c1f3d --- /dev/null +++ b/queue-6.5/asoc-mediatek-mt8188-mt6359-support-dynamic-pinctrl.patch @@ -0,0 +1,80 @@ +From 5d31a4fd3fa4636aae09547b78e797bcefcb4a15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 10:49:33 +0800 +Subject: ASoC: mediatek: mt8188-mt6359: support dynamic pinctrl + +From: Trevor Wu + +[ Upstream commit d601bb78f06b9e3cbb52e6b87b88add9920a11b6 ] + +To avoid power leakage, it is recommended to replace the default pinctrl +state with dynamic pinctrl since certain audio pinmux functions can +remain in a HIGH state even when audio is disabled. Linking pinctrl with +DAPM using SND_SOC_DAPM_PINCTRL will ensure that audio pins remain in +GPIO mode by default and only switch to an audio function when necessary. + +Signed-off-by: Trevor Wu +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230825024935.10878-2-trevor.wu@mediatek.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/mediatek/mt8188/mt8188-mt6359.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c +index ac69c23e0da1c..7048ff52ab86a 100644 +--- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c ++++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c +@@ -246,6 +246,11 @@ static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = { + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_SINK("HDMI"), + SND_SOC_DAPM_SINK("DP"), ++ ++ /* dynamic pinctrl */ ++ SND_SOC_DAPM_PINCTRL("ETDM_SPK_PIN", "aud_etdm_spk_on", "aud_etdm_spk_off"), ++ SND_SOC_DAPM_PINCTRL("ETDM_HP_PIN", "aud_etdm_hp_on", "aud_etdm_hp_off"), ++ SND_SOC_DAPM_PINCTRL("MTKAIF_PIN", "aud_mtkaif_on", "aud_mtkaif_off"), + }; + + static const struct snd_kcontrol_new mt8188_mt6359_controls[] = { +@@ -267,6 +272,7 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; ++ struct snd_soc_dapm_widget *pin_w = NULL, *w; + struct mtk_base_afe *afe; + struct mt8188_afe_private *afe_priv; + struct mtkaif_param *param; +@@ -306,6 +312,18 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) + return 0; + } + ++ for_each_card_widgets(rtd->card, w) { ++ if (!strcmp(w->name, "MTKAIF_PIN")) { ++ pin_w = w; ++ break; ++ } ++ } ++ ++ if (pin_w) ++ dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_PRE_PMU); ++ else ++ dev_dbg(afe->dev, "%s(), no pinmux widget, please check if default on\n", __func__); ++ + pm_runtime_get_sync(afe->dev); + mt6359_mtkaif_calibration_enable(cmpnt_codec); + +@@ -403,6 +421,9 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) + for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++) + param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i]; + ++ if (pin_w) ++ dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_POST_PMD); ++ + dev_dbg(afe->dev, "%s(), end, calibration ok %d\n", + __func__, param->mtkaif_calibration_ok); + +-- +2.42.0 + diff --git a/queue-6.5/asoc-soc-card-add-storage-for-pci-ssid.patch b/queue-6.5/asoc-soc-card-add-storage-for-pci-ssid.patch new file mode 100644 index 00000000000..13ab6b0404a --- /dev/null +++ b/queue-6.5/asoc-soc-card-add-storage-for-pci-ssid.patch @@ -0,0 +1,122 @@ +From 8450094d5484d7ea4ad7362bc216636b6202708b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:32:04 +0100 +Subject: ASoC: soc-card: Add storage for PCI SSID + +From: Richard Fitzgerald + +[ Upstream commit 47f56e38a199bd45514b8e0142399cba4feeaf1a ] + +Add members to struct snd_soc_card to store the PCI subsystem ID (SSID) +of the soundcard. + +The PCI specification provides two registers to store a vendor-specific +SSID that can be read by drivers to uniquely identify a particular +"soundcard". This is defined in the PCI specification to distinguish +products that use the same silicon (and therefore have the same silicon +ID) so that product-specific differences can be applied. + +PCI only defines 0xFFFF as an invalid value. 0x0000 is not defined as +invalid. So the usual pattern of zero-filling the struct and then +assuming a zero value unset will not work. A flag is included to +indicate when the SSID information has been filled in. + +Unlike DMI information, which has a free-format entirely up to the vendor, +the PCI SSID has a strictly defined format and a registry of vendor IDs. + +It is usual in Windows drivers that the SSID is used as the sole identifier +of the specific end-product and the Windows driver contains tables mapping +that to information about the hardware setup, rather than using ACPI +properties. + +This SSID is important information for ASoC components that need to apply +hardware-specific configuration on PCI-based systems. + +As the SSID is a generic part of the PCI specification and is treated as +identifying the "soundcard", it is reasonable to include this information +in struct snd_soc_card, instead of components inventing their own custom +ways to pass this information around. + +Signed-off-by: Richard Fitzgerald +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20230912163207.3498161-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/soc-card.h | 37 +++++++++++++++++++++++++++++++++++++ + include/sound/soc.h | 11 +++++++++++ + 2 files changed, 48 insertions(+) + +diff --git a/include/sound/soc-card.h b/include/sound/soc-card.h +index fc94dfb0021fd..e8ff2e089cd00 100644 +--- a/include/sound/soc-card.h ++++ b/include/sound/soc-card.h +@@ -59,6 +59,43 @@ int snd_soc_card_add_dai_link(struct snd_soc_card *card, + void snd_soc_card_remove_dai_link(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link); + ++#ifdef CONFIG_PCI ++static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card, ++ unsigned short vendor, ++ unsigned short device) ++{ ++ card->pci_subsystem_vendor = vendor; ++ card->pci_subsystem_device = device; ++ card->pci_subsystem_set = true; ++} ++ ++static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card, ++ unsigned short *vendor, ++ unsigned short *device) ++{ ++ if (!card->pci_subsystem_set) ++ return -ENOENT; ++ ++ *vendor = card->pci_subsystem_vendor; ++ *device = card->pci_subsystem_device; ++ ++ return 0; ++} ++#else /* !CONFIG_PCI */ ++static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card, ++ unsigned short vendor, ++ unsigned short device) ++{ ++} ++ ++static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card, ++ unsigned short *vendor, ++ unsigned short *device) ++{ ++ return -ENOENT; ++} ++#endif /* CONFIG_PCI */ ++ + /* device driver data */ + static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, + void *data) +diff --git a/include/sound/soc.h b/include/sound/soc.h +index cf34810882347..0c54b343d3e5d 100644 +--- a/include/sound/soc.h ++++ b/include/sound/soc.h +@@ -931,6 +931,17 @@ struct snd_soc_card { + #ifdef CONFIG_DMI + char dmi_longname[80]; + #endif /* CONFIG_DMI */ ++ ++#ifdef CONFIG_PCI ++ /* ++ * PCI does not define 0 as invalid, so pci_subsystem_set indicates ++ * whether a value has been written to these fields. ++ */ ++ unsigned short pci_subsystem_vendor; ++ unsigned short pci_subsystem_device; ++ bool pci_subsystem_set; ++#endif /* CONFIG_PCI */ ++ + char topology_shortname[32]; + + struct device *dev; +-- +2.42.0 + diff --git a/queue-6.5/asoc-sof-ipc4-handle-exception_caught-notification-f.patch b/queue-6.5/asoc-sof-ipc4-handle-exception_caught-notification-f.patch new file mode 100644 index 00000000000..8ee5469cb3f --- /dev/null +++ b/queue-6.5/asoc-sof-ipc4-handle-exception_caught-notification-f.patch @@ -0,0 +1,45 @@ +From 3b460cd0ec8d4c84818282296c0628648f0da281 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 12:24:16 +0300 +Subject: ASoC: SOF: ipc4: handle EXCEPTION_CAUGHT notification from firmware +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rander Wang + +[ Upstream commit c1c48fd6bbe788458e3685fea74bdb3cb148ff93 ] + +Driver will receive exception IPC message and process it by +snd_sof_dsp_panic. + +Signed-off-by: Rander Wang +Reviewed-by: Péter Ujfalusi +Reviewed-by: Kai Vehmanen +Reviewed-by: Pierre-Louis Bossart +Reviewed-by: Guennadi Liakhovetski +Signed-off-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/20230919092416.4137-10-peter.ujfalusi@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/ipc4.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c +index ab6eddd91bb77..1b09496733fb8 100644 +--- a/sound/soc/sof/ipc4.c ++++ b/sound/soc/sof/ipc4.c +@@ -614,6 +614,9 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev) + case SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS: + sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary)); + break; ++ case SOF_IPC4_NOTIFY_EXCEPTION_CAUGHT: ++ snd_sof_dsp_panic(sdev, 0, true); ++ break; + default: + dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n", + ipc4_msg->primary, ipc4_msg->extension); +-- +2.42.0 + diff --git a/queue-6.5/asoc-sof-pass-pci-ssid-to-machine-driver.patch b/queue-6.5/asoc-sof-pass-pci-ssid-to-machine-driver.patch new file mode 100644 index 00000000000..404f80804c6 --- /dev/null +++ b/queue-6.5/asoc-sof-pass-pci-ssid-to-machine-driver.patch @@ -0,0 +1,132 @@ +From 87d873f652d45a04df1fbe0b297f17dd1574a411 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 17:32:05 +0100 +Subject: ASoC: SOF: Pass PCI SSID to machine driver + +From: Richard Fitzgerald + +[ Upstream commit ba2de401d32625fe538d3f2c00ca73740dd2d516 ] + +Pass the PCI SSID of the audio interface through to the machine driver. +This allows the machine driver to use the SSID to uniquely identify the +specific hardware configuration and apply any platform-specific +configuration. + +struct snd_sof_pdata is passed around inside the SOF code, but it then +passes configuration information to the machine driver through +struct snd_soc_acpi_mach and struct snd_soc_acpi_mach_params. So SSID +information has been added to both snd_sof_pdata and +snd_soc_acpi_mach_params. + +PCI does not define 0x0000 as an invalid value so we can't use zero to +indicate that the struct member was not written. Instead a flag is +included to indicate that a value has been written to the +subsystem_vendor and subsystem_device members. + +sof_pci_probe() creates the struct snd_sof_pdata. It is passed a struct +pci_dev so it can fill in the SSID value. + +sof_machine_check() finds the appropriate struct snd_soc_acpi_mach. It +copies the SSID information across to the struct snd_soc_acpi_mach_params. +This done before calling any custom set_mach_params() so that it could be +used by the set_mach_params() callback to apply variant params. + +The machine driver receives the struct snd_soc_acpi_mach as its +platform_data. + +Signed-off-by: Richard Fitzgerald +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20230912163207.3498161-3-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/sound/soc-acpi.h | 7 +++++++ + include/sound/sof.h | 8 ++++++++ + sound/soc/sof/sof-audio.c | 7 +++++++ + sound/soc/sof/sof-pci-dev.c | 8 ++++++++ + 4 files changed, 30 insertions(+) + +diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h +index 528279056b3ab..1a5f90b0a5463 100644 +--- a/include/sound/soc-acpi.h ++++ b/include/sound/soc-acpi.h +@@ -67,6 +67,10 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) + * @i2s_link_mask: I2S/TDM links enabled on the board + * @num_dai_drivers: number of elements in @dai_drivers + * @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode ++ * @subsystem_vendor: optional PCI SSID vendor value ++ * @subsystem_device: optional PCI SSID device value ++ * @subsystem_id_set: true if a value has been written to ++ * subsystem_vendor and subsystem_device. + */ + struct snd_soc_acpi_mach_params { + u32 acpi_ipc_irq_index; +@@ -79,6 +83,9 @@ struct snd_soc_acpi_mach_params { + u32 i2s_link_mask; + u32 num_dai_drivers; + struct snd_soc_dai_driver *dai_drivers; ++ unsigned short subsystem_vendor; ++ unsigned short subsystem_device; ++ bool subsystem_id_set; + }; + + /** +diff --git a/include/sound/sof.h b/include/sound/sof.h +index d3c41f87ac319..51294f2ba302c 100644 +--- a/include/sound/sof.h ++++ b/include/sound/sof.h +@@ -64,6 +64,14 @@ struct snd_sof_pdata { + const char *name; + const char *platform; + ++ /* ++ * PCI SSID. As PCI does not define 0 as invalid, the subsystem_id_set ++ * flag indicates that a value has been written to these members. ++ */ ++ unsigned short subsystem_vendor; ++ unsigned short subsystem_device; ++ bool subsystem_id_set; ++ + struct device *dev; + + /* +diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c +index e5405f854a910..563fe6f7789f7 100644 +--- a/sound/soc/sof/sof-audio.c ++++ b/sound/soc/sof/sof-audio.c +@@ -1032,6 +1032,13 @@ int sof_machine_check(struct snd_sof_dev *sdev) + mach = snd_sof_machine_select(sdev); + if (mach) { + sof_pdata->machine = mach; ++ ++ if (sof_pdata->subsystem_id_set) { ++ mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; ++ mach->mach_params.subsystem_device = sof_pdata->subsystem_device; ++ mach->mach_params.subsystem_id_set = true; ++ } ++ + snd_sof_set_mach_params(mach, sdev); + return 0; + } +diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c +index f42c85df88a80..69a2352f2e1a0 100644 +--- a/sound/soc/sof/sof-pci-dev.c ++++ b/sound/soc/sof/sof-pci-dev.c +@@ -221,6 +221,14 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) + return ret; + + sof_pdata->name = pci_name(pci); ++ ++ /* PCI defines a vendor ID of 0xFFFF as invalid. */ ++ if (pci->subsystem_vendor != 0xFFFF) { ++ sof_pdata->subsystem_vendor = pci->subsystem_vendor; ++ sof_pdata->subsystem_device = pci->subsystem_device; ++ sof_pdata->subsystem_id_set = true; ++ } ++ + sof_pdata->desc = desc; + sof_pdata->dev = dev; + +-- +2.42.0 + diff --git a/queue-6.5/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch b/queue-6.5/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch new file mode 100644 index 00000000000..cd77bb20090 --- /dev/null +++ b/queue-6.5/asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch @@ -0,0 +1,47 @@ +From 63b8eb8e1c8c099d1de5845968638152f05678c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 07:23:38 +0200 +Subject: ASoC: ti: omap-mcbsp: Fix runtime PM underflow warnings + +From: Tony Lindgren + +[ Upstream commit fbb74e56378d8306f214658e3d525a8b3f000c5a ] + +We need to check for an active device as otherwise we get warnings +for some mcbsp instances for "Runtime PM usage count underflow!". + +Reported-by: Andreas Kemnade +Signed-off-by: Tony Lindgren +Link: https://lore.kernel.org/r/20231030052340.13415-1-tony@atomide.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/ti/omap-mcbsp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c +index 21fa7b9787997..94c514e57eef9 100644 +--- a/sound/soc/ti/omap-mcbsp.c ++++ b/sound/soc/ti/omap-mcbsp.c +@@ -74,14 +74,16 @@ static int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) + return -EINVAL; + } + +- pm_runtime_put_sync(mcbsp->dev); ++ if (mcbsp->active) ++ pm_runtime_put_sync(mcbsp->dev); + + r = clk_set_parent(mcbsp->fclk, fck_src); + if (r) + dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n", + src); + +- pm_runtime_get_sync(mcbsp->dev); ++ if (mcbsp->active) ++ pm_runtime_get_sync(mcbsp->dev); + + clk_put(fck_src); + +-- +2.42.0 + diff --git a/queue-6.5/atl1c-work-around-the-dma-rx-overflow-issue.patch b/queue-6.5/atl1c-work-around-the-dma-rx-overflow-issue.patch new file mode 100644 index 00000000000..a5914c2afa6 --- /dev/null +++ b/queue-6.5/atl1c-work-around-the-dma-rx-overflow-issue.patch @@ -0,0 +1,173 @@ +From 339ad83eac5241b83bf8a0a9a5007fdee2d9574d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:07:11 +0800 +Subject: atl1c: Work around the DMA RX overflow issue + +From: Sieng-Piaw Liew + +[ Upstream commit 86565682e9053e5deb128193ea9e88531bbae9cf ] + +This is based on alx driver commit 881d0327db37 ("net: alx: Work around +the DMA RX overflow issue"). + +The alx and atl1c drivers had RX overflow error which was why a custom +allocator was created to avoid certain addresses. The simpler workaround +then created for alx driver, but not for atl1c due to lack of tester. + +Instead of using a custom allocator, check the allocated skb address and +use skb_reserve() to move away from problematic 0x...fc0 address. + +Tested on AR8131 on Acer 4540. + +Signed-off-by: Sieng-Piaw Liew +Link: https://lore.kernel.org/r/20230912010711.12036-1-liew.s.piaw@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/atheros/atl1c/atl1c.h | 3 - + .../net/ethernet/atheros/atl1c/atl1c_main.c | 67 +++++-------------- + 2 files changed, 16 insertions(+), 54 deletions(-) + +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h +index 43d821fe7a542..63ba64dbb7310 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c.h ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h +@@ -504,15 +504,12 @@ struct atl1c_rrd_ring { + u16 next_to_use; + u16 next_to_clean; + struct napi_struct napi; +- struct page *rx_page; +- unsigned int rx_page_offset; + }; + + /* board specific private data structure */ + struct atl1c_adapter { + struct net_device *netdev; + struct pci_dev *pdev; +- unsigned int rx_frag_size; + struct atl1c_hw hw; + struct atl1c_hw_stats hw_stats; + struct mii_if_info mii; /* MII interface info */ +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +index 940c5d1ff9cfc..74b78164cf74a 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -483,15 +483,10 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p) + static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, + struct net_device *dev) + { +- unsigned int head_size; + int mtu = dev->mtu; + + adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? + roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; +- +- head_size = SKB_DATA_ALIGN(adapter->rx_buffer_len + NET_SKB_PAD + NET_IP_ALIGN) + +- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- adapter->rx_frag_size = roundup_pow_of_two(head_size); + } + + static netdev_features_t atl1c_fix_features(struct net_device *netdev, +@@ -964,7 +959,6 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) + static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) + { + struct pci_dev *pdev = adapter->pdev; +- int i; + + dma_free_coherent(&pdev->dev, adapter->ring_header.size, + adapter->ring_header.desc, adapter->ring_header.dma); +@@ -977,12 +971,6 @@ static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) + kfree(adapter->tpd_ring[0].buffer_info); + adapter->tpd_ring[0].buffer_info = NULL; + } +- for (i = 0; i < adapter->rx_queue_count; ++i) { +- if (adapter->rrd_ring[i].rx_page) { +- put_page(adapter->rrd_ring[i].rx_page); +- adapter->rrd_ring[i].rx_page = NULL; +- } +- } + } + + /** +@@ -1754,48 +1742,11 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, + skb_checksum_none_assert(skb); + } + +-static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter, +- u32 queue, bool napi_mode) +-{ +- struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue]; +- struct sk_buff *skb; +- struct page *page; +- +- if (adapter->rx_frag_size > PAGE_SIZE) { +- if (likely(napi_mode)) +- return napi_alloc_skb(&rrd_ring->napi, +- adapter->rx_buffer_len); +- else +- return netdev_alloc_skb_ip_align(adapter->netdev, +- adapter->rx_buffer_len); +- } +- +- page = rrd_ring->rx_page; +- if (!page) { +- page = alloc_page(GFP_ATOMIC); +- if (unlikely(!page)) +- return NULL; +- rrd_ring->rx_page = page; +- rrd_ring->rx_page_offset = 0; +- } +- +- skb = build_skb(page_address(page) + rrd_ring->rx_page_offset, +- adapter->rx_frag_size); +- if (likely(skb)) { +- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); +- rrd_ring->rx_page_offset += adapter->rx_frag_size; +- if (rrd_ring->rx_page_offset >= PAGE_SIZE) +- rrd_ring->rx_page = NULL; +- else +- get_page(page); +- } +- return skb; +-} +- + static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue, + bool napi_mode) + { + struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[queue]; ++ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue]; + struct pci_dev *pdev = adapter->pdev; + struct atl1c_buffer *buffer_info, *next_info; + struct sk_buff *skb; +@@ -1814,13 +1765,27 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue, + while (next_info->flags & ATL1C_BUFFER_FREE) { + rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); + +- skb = atl1c_alloc_skb(adapter, queue, napi_mode); ++ /* When DMA RX address is set to something like ++ * 0x....fc0, it will be very likely to cause DMA ++ * RFD overflow issue. ++ * ++ * To work around it, we apply rx skb with 64 bytes ++ * longer space, and offset the address whenever ++ * 0x....fc0 is detected. ++ */ ++ if (likely(napi_mode)) ++ skb = napi_alloc_skb(&rrd_ring->napi, adapter->rx_buffer_len + 64); ++ else ++ skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len + 64); + if (unlikely(!skb)) { + if (netif_msg_rx_err(adapter)) + dev_warn(&pdev->dev, "alloc rx buffer failed\n"); + break; + } + ++ if (((unsigned long)skb->data & 0xfff) == 0xfc0) ++ skb_reserve(skb, 64); ++ + /* + * Make buffer alignment 2 beyond a 16 byte boundary + * this will result in a 16 byte aligned IP header after +-- +2.42.0 + diff --git a/queue-6.5/atm-iphase-do-pci-error-checks-on-own-line.patch b/queue-6.5/atm-iphase-do-pci-error-checks-on-own-line.patch new file mode 100644 index 00000000000..b0c0d9845dd --- /dev/null +++ b/queue-6.5/atm-iphase-do-pci-error-checks-on-own-line.patch @@ -0,0 +1,68 @@ +From 77a7152f64b837a6305f6dcd943a345789bce13e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 15:53:51 +0300 +Subject: atm: iphase: Do PCI error checks on own line +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit c28742447ca9879b52fbaf022ad844f0ffcd749c ] + +In get_esi() PCI errors are checked inside line-split "if" conditions (in +addition to the file not following the coding style). To make the code in +get_esi() more readable, fix the coding style and use the usual error +handling pattern with a separate variable. + +In addition, initialization of 'error' variable at declaration is not +needed. + +No functional changes intended. + +Link: https://lore.kernel.org/r/20230911125354.25501-4-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/atm/iphase.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c +index 3241486869530..9bba8f280a4d4 100644 +--- a/drivers/atm/iphase.c ++++ b/drivers/atm/iphase.c +@@ -2291,19 +2291,21 @@ static int get_esi(struct atm_dev *dev) + static int reset_sar(struct atm_dev *dev) + { + IADEV *iadev; +- int i, error = 1; ++ int i, error; + unsigned int pci[64]; + + iadev = INPH_IA_DEV(dev); +- for(i=0; i<64; i++) +- if ((error = pci_read_config_dword(iadev->pci, +- i*4, &pci[i])) != PCIBIOS_SUCCESSFUL) +- return error; ++ for (i = 0; i < 64; i++) { ++ error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]); ++ if (error != PCIBIOS_SUCCESSFUL) ++ return error; ++ } + writel(0, iadev->reg+IPHASE5575_EXT_RESET); +- for(i=0; i<64; i++) +- if ((error = pci_write_config_dword(iadev->pci, +- i*4, pci[i])) != PCIBIOS_SUCCESSFUL) +- return error; ++ for (i = 0; i < 64; i++) { ++ error = pci_write_config_dword(iadev->pci, i * 4, pci[i]); ++ if (error != PCIBIOS_SUCCESSFUL) ++ return error; ++ } + udelay(5); + return 0; + } +-- +2.42.0 + diff --git a/queue-6.5/blk-mq-make-sure-active-queue-usage-is-held-for-bio_.patch b/queue-6.5/blk-mq-make-sure-active-queue-usage-is-held-for-bio_.patch new file mode 100644 index 00000000000..0b26103ae4c --- /dev/null +++ b/queue-6.5/blk-mq-make-sure-active-queue-usage-is-held-for-bio_.patch @@ -0,0 +1,169 @@ +From 43e0b8f7963664a2501b422d7196d42c4db80968 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 11:52:31 +0800 +Subject: blk-mq: make sure active queue usage is held for bio_integrity_prep() + +From: Christoph Hellwig + +[ Upstream commit b0077e269f6c152e807fdac90b58caf012cdbaab ] + +blk_integrity_unregister() can come if queue usage counter isn't held +for one bio with integrity prepared, so this request may be completed with +calling profile->complete_fn, then kernel panic. + +Another constraint is that bio_integrity_prep() needs to be called +before bio merge. + +Fix the issue by: + +- call bio_integrity_prep() with one queue usage counter grabbed reliably + +- call bio_integrity_prep() before bio merge + +Fixes: 900e080752025f00 ("block: move queue enter logic into blk_mq_submit_bio()") +Reported-by: Yi Zhang +Cc: Christoph Hellwig +Signed-off-by: Ming Lei +Tested-by: Yi Zhang +Link: https://lore.kernel.org/r/20231113035231.2708053-1-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-mq.c | 75 +++++++++++++++++++++++++------------------------- + 1 file changed, 38 insertions(+), 37 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index c21bc81a790ff..5fb31b9a16403 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -2874,11 +2874,8 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, + }; + struct request *rq; + +- if (unlikely(bio_queue_enter(bio))) +- return NULL; +- + if (blk_mq_attempt_bio_merge(q, bio, nsegs)) +- goto queue_exit; ++ return NULL; + + rq_qos_throttle(q, bio); + +@@ -2894,35 +2891,23 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, + rq_qos_cleanup(q, bio); + if (bio->bi_opf & REQ_NOWAIT) + bio_wouldblock_error(bio); +-queue_exit: +- blk_queue_exit(q); + return NULL; + } + +-static inline struct request *blk_mq_get_cached_request(struct request_queue *q, +- struct blk_plug *plug, struct bio **bio, unsigned int nsegs) ++/* return true if this @rq can be used for @bio */ ++static bool blk_mq_can_use_cached_rq(struct request *rq, struct blk_plug *plug, ++ struct bio *bio) + { +- struct request *rq; +- enum hctx_type type, hctx_type; ++ enum hctx_type type = blk_mq_get_hctx_type(bio->bi_opf); ++ enum hctx_type hctx_type = rq->mq_hctx->type; + +- if (!plug) +- return NULL; +- rq = rq_list_peek(&plug->cached_rq); +- if (!rq || rq->q != q) +- return NULL; ++ WARN_ON_ONCE(rq_list_peek(&plug->cached_rq) != rq); + +- if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) { +- *bio = NULL; +- return NULL; +- } +- +- type = blk_mq_get_hctx_type((*bio)->bi_opf); +- hctx_type = rq->mq_hctx->type; + if (type != hctx_type && + !(type == HCTX_TYPE_READ && hctx_type == HCTX_TYPE_DEFAULT)) +- return NULL; +- if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) +- return NULL; ++ return false; ++ if (op_is_flush(rq->cmd_flags) != op_is_flush(bio->bi_opf)) ++ return false; + + /* + * If any qos ->throttle() end up blocking, we will have flushed the +@@ -2930,12 +2915,12 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, + * before we throttle. + */ + plug->cached_rq = rq_list_next(rq); +- rq_qos_throttle(q, *bio); ++ rq_qos_throttle(rq->q, bio); + + blk_mq_rq_time_init(rq, 0); +- rq->cmd_flags = (*bio)->bi_opf; ++ rq->cmd_flags = bio->bi_opf; + INIT_LIST_HEAD(&rq->queuelist); +- return rq; ++ return true; + } + + static void bio_set_ioprio(struct bio *bio) +@@ -2965,7 +2950,7 @@ void blk_mq_submit_bio(struct bio *bio) + struct blk_plug *plug = blk_mq_plug(bio); + const int is_sync = op_is_sync(bio->bi_opf); + struct blk_mq_hw_ctx *hctx; +- struct request *rq; ++ struct request *rq = NULL; + unsigned int nr_segs = 1; + blk_status_t ret; + +@@ -2976,20 +2961,36 @@ void blk_mq_submit_bio(struct bio *bio) + return; + } + +- if (!bio_integrity_prep(bio)) +- return; +- + bio_set_ioprio(bio); + +- rq = blk_mq_get_cached_request(q, plug, &bio, nr_segs); +- if (!rq) { +- if (!bio) ++ if (plug) { ++ rq = rq_list_peek(&plug->cached_rq); ++ if (rq && rq->q != q) ++ rq = NULL; ++ } ++ if (rq) { ++ if (!bio_integrity_prep(bio)) + return; +- rq = blk_mq_get_new_requests(q, plug, bio, nr_segs); +- if (unlikely(!rq)) ++ if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) + return; ++ if (blk_mq_can_use_cached_rq(rq, plug, bio)) ++ goto done; ++ percpu_ref_get(&q->q_usage_counter); ++ } else { ++ if (unlikely(bio_queue_enter(bio))) ++ return; ++ if (!bio_integrity_prep(bio)) ++ goto fail; ++ } ++ ++ rq = blk_mq_get_new_requests(q, plug, bio, nr_segs); ++ if (unlikely(!rq)) { ++fail: ++ blk_queue_exit(q); ++ return; + } + ++done: + trace_block_getrq(bio); + + rq_qos_track(q, rq, bio); +-- +2.42.0 + diff --git a/queue-6.5/bluetooth-btusb-add-date-evt_skb-is-null-check.patch b/queue-6.5/bluetooth-btusb-add-date-evt_skb-is-null-check.patch new file mode 100644 index 00000000000..5918be13383 --- /dev/null +++ b/queue-6.5/bluetooth-btusb-add-date-evt_skb-is-null-check.patch @@ -0,0 +1,71 @@ +From d6faad89c012d935296fbd1cdb5eefb2f1c33042 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 13:14:47 +0800 +Subject: Bluetooth: btusb: Add date->evt_skb is NULL check + +From: youwan Wang + +[ Upstream commit 624820f7c8826dd010e8b1963303c145f99816e9 ] + +fix crash because of null pointers + +[ 6104.969662] BUG: kernel NULL pointer dereference, address: 00000000000000c8 +[ 6104.969667] #PF: supervisor read access in kernel mode +[ 6104.969668] #PF: error_code(0x0000) - not-present page +[ 6104.969670] PGD 0 P4D 0 +[ 6104.969673] Oops: 0000 [#1] SMP NOPTI +[ 6104.969684] RIP: 0010:btusb_mtk_hci_wmt_sync+0x144/0x220 [btusb] +[ 6104.969688] RSP: 0018:ffffb8d681533d48 EFLAGS: 00010246 +[ 6104.969689] RAX: 0000000000000000 RBX: ffff8ad560bb2000 RCX: 0000000000000006 +[ 6104.969691] RDX: 0000000000000000 RSI: ffffb8d681533d08 RDI: 0000000000000000 +[ 6104.969692] RBP: ffffb8d681533d70 R08: 0000000000000001 R09: 0000000000000001 +[ 6104.969694] R10: 0000000000000001 R11: 00000000fa83b2da R12: ffff8ad461d1d7c0 +[ 6104.969695] R13: 0000000000000000 R14: ffff8ad459618c18 R15: ffffb8d681533d90 +[ 6104.969697] FS: 00007f5a1cab9d40(0000) GS:ffff8ad578200000(0000) knlGS:00000 +[ 6104.969699] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 6104.969700] CR2: 00000000000000c8 CR3: 000000018620c001 CR4: 0000000000760ef0 +[ 6104.969701] PKRU: 55555554 +[ 6104.969702] Call Trace: +[ 6104.969708] btusb_mtk_shutdown+0x44/0x80 [btusb] +[ 6104.969732] hci_dev_do_close+0x470/0x5c0 [bluetooth] +[ 6104.969748] hci_rfkill_set_block+0x56/0xa0 [bluetooth] +[ 6104.969753] rfkill_set_block+0x92/0x160 +[ 6104.969755] rfkill_fop_write+0x136/0x1e0 +[ 6104.969759] __vfs_write+0x18/0x40 +[ 6104.969761] vfs_write+0xdf/0x1c0 +[ 6104.969763] ksys_write+0xb1/0xe0 +[ 6104.969765] __x64_sys_write+0x1a/0x20 +[ 6104.969769] do_syscall_64+0x51/0x180 +[ 6104.969771] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 6104.969773] RIP: 0033:0x7f5a21f18fef +[ 6104.9] RSP: 002b:00007ffeefe39010 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 +[ 6104.969780] RAX: ffffffffffffffda RBX: 000055c10a7560a0 RCX: 00007f5a21f18fef +[ 6104.969781] RDX: 0000000000000008 RSI: 00007ffeefe39060 RDI: 0000000000000012 +[ 6104.969782] RBP: 00007ffeefe39060 R08: 0000000000000000 R09: 0000000000000017 +[ 6104.969784] R10: 00007ffeefe38d97 R11: 0000000000000293 R12: 0000000000000002 +[ 6104.969785] R13: 00007ffeefe39220 R14: 00007ffeefe391a0 R15: 000055c10a72acf0 + +Signed-off-by: youwan Wang +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index ca9e2a210fff2..ea29469fe0cff 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -2803,6 +2803,9 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, + goto err_free_wc; + } + ++ if (data->evt_skb == NULL) ++ goto err_free_wc; ++ + /* Parse and handle the return WMT event */ + wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data; + if (wmt_evt->whdr.op != hdr->op) { +-- +2.42.0 + diff --git a/queue-6.5/bluetooth-fix-double-free-in-hci_conn_cleanup.patch b/queue-6.5/bluetooth-fix-double-free-in-hci_conn_cleanup.patch new file mode 100644 index 00000000000..3f5f5d63b43 --- /dev/null +++ b/queue-6.5/bluetooth-fix-double-free-in-hci_conn_cleanup.patch @@ -0,0 +1,139 @@ +From 0fa5d60c6a1442363cca4a1105a1dc3a00b14dd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 12:30:55 +0200 +Subject: Bluetooth: Fix double free in hci_conn_cleanup + +From: ZhengHan Wang + +[ Upstream commit a85fb91e3d728bdfc80833167e8162cce8bc7004 ] + +syzbot reports a slab use-after-free in hci_conn_hash_flush [1]. +After releasing an object using hci_conn_del_sysfs in the +hci_conn_cleanup function, releasing the same object again +using the hci_dev_put and hci_conn_put functions causes a double free. +Here's a simplified flow: + +hci_conn_del_sysfs: + hci_dev_put + put_device + kobject_put + kref_put + kobject_release + kobject_cleanup + kfree_const + kfree(name) + +hci_dev_put: + ... + kfree(name) + +hci_conn_put: + put_device + ... + kfree(name) + +This patch drop the hci_dev_put and hci_conn_put function +call in hci_conn_cleanup function, because the object is +freed in hci_conn_del_sysfs function. + +This patch also fixes the refcounting in hci_conn_add_sysfs() and +hci_conn_del_sysfs() to take into account device_add() failures. + +This fixes CVE-2023-28464. + +Link: https://syzkaller.appspot.com/bug?id=1bb51491ca5df96a5f724899d1dbb87afda61419 [1] + +Signed-off-by: ZhengHan Wang +Co-developed-by: Luiz Augusto von Dentz +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 6 ++---- + net/bluetooth/hci_sysfs.c | 23 ++++++++++++----------- + 2 files changed, 14 insertions(+), 15 deletions(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 4e03642488230..c090627ff9751 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -172,13 +172,11 @@ static void hci_conn_cleanup(struct hci_conn *conn) + hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); + } + +- hci_conn_del_sysfs(conn); +- + debugfs_remove_recursive(conn->debugfs); + +- hci_dev_put(hdev); ++ hci_conn_del_sysfs(conn); + +- hci_conn_put(conn); ++ hci_dev_put(hdev); + } + + static void hci_acl_create_connection(struct hci_conn *conn) +diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c +index 15b33579007cb..367e32fe30eb8 100644 +--- a/net/bluetooth/hci_sysfs.c ++++ b/net/bluetooth/hci_sysfs.c +@@ -35,7 +35,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + conn->dev.type = &bt_link; + conn->dev.class = &bt_class; +@@ -48,27 +48,30 @@ void hci_conn_add_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; + +- BT_DBG("conn %p", conn); ++ bt_dev_dbg(hdev, "conn %p", conn); + + if (device_is_registered(&conn->dev)) + return; + + dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); + +- if (device_add(&conn->dev) < 0) { ++ if (device_add(&conn->dev) < 0) + bt_dev_err(hdev, "failed to register connection device"); +- return; +- } +- +- hci_dev_hold(hdev); + } + + void hci_conn_del_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; + +- if (!device_is_registered(&conn->dev)) ++ bt_dev_dbg(hdev, "conn %p", conn); ++ ++ if (!device_is_registered(&conn->dev)) { ++ /* If device_add() has *not* succeeded, use *only* put_device() ++ * to drop the reference count. ++ */ ++ put_device(&conn->dev); + return; ++ } + + while (1) { + struct device *dev; +@@ -80,9 +83,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn) + put_device(dev); + } + +- device_del(&conn->dev); +- +- hci_dev_put(hdev); ++ device_unregister(&conn->dev); + } + + static void bt_host_release(struct device *dev) +-- +2.42.0 + diff --git a/queue-6.5/bonding-stop-the-device-in-bond_setup_by_slave.patch b/queue-6.5/bonding-stop-the-device-in-bond_setup_by_slave.patch new file mode 100644 index 00000000000..85b086cfcfa --- /dev/null +++ b/queue-6.5/bonding-stop-the-device-in-bond_setup_by_slave.patch @@ -0,0 +1,133 @@ +From 8e7d26ddfeee8e4593f38355cbf0fa18b1a72322 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 18:01:02 +0000 +Subject: bonding: stop the device in bond_setup_by_slave() + +From: Eric Dumazet + +[ Upstream commit 3cffa2ddc4d3fcf70cde361236f5a614f81a09b2 ] + +Commit 9eed321cde22 ("net: lapbether: only support ethernet devices") +has been able to keep syzbot away from net/lapb, until today. + +In the following splat [1], the issue is that a lapbether device has +been created on a bonding device without members. Then adding a non +ARPHRD_ETHER member forced the bonding master to change its type. + +The fix is to make sure we call dev_close() in bond_setup_by_slave() +so that the potential linked lapbether devices (or any other devices +having assumptions on the physical device) are removed. + +A similar bug has been addressed in commit 40baec225765 +("bonding: fix panic on non-ARPHRD_ETHER enslave failure") + +[1] +skbuff: skb_under_panic: text:ffff800089508810 len:44 put:40 head:ffff0000c78e7c00 data:ffff0000c78e7bea tail:0x16 end:0x140 dev:bond0 +kernel BUG at net/core/skbuff.c:192 ! +Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP +Modules linked in: +CPU: 0 PID: 6007 Comm: syz-executor383 Not tainted 6.6.0-rc3-syzkaller-gbf6547d8715b #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/04/2023 +pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +pc : skb_panic net/core/skbuff.c:188 [inline] +pc : skb_under_panic+0x13c/0x140 net/core/skbuff.c:202 +lr : skb_panic net/core/skbuff.c:188 [inline] +lr : skb_under_panic+0x13c/0x140 net/core/skbuff.c:202 +sp : ffff800096a06aa0 +x29: ffff800096a06ab0 x28: ffff800096a06ba0 x27: dfff800000000000 +x26: ffff0000ce9b9b50 x25: 0000000000000016 x24: ffff0000c78e7bea +x23: ffff0000c78e7c00 x22: 000000000000002c x21: 0000000000000140 +x20: 0000000000000028 x19: ffff800089508810 x18: ffff800096a06100 +x17: 0000000000000000 x16: ffff80008a629a3c x15: 0000000000000001 +x14: 1fffe00036837a32 x13: 0000000000000000 x12: 0000000000000000 +x11: 0000000000000201 x10: 0000000000000000 x9 : cb50b496c519aa00 +x8 : cb50b496c519aa00 x7 : 0000000000000001 x6 : 0000000000000001 +x5 : ffff800096a063b8 x4 : ffff80008e280f80 x3 : ffff8000805ad11c +x2 : 0000000000000001 x1 : 0000000100000201 x0 : 0000000000000086 +Call trace: +skb_panic net/core/skbuff.c:188 [inline] +skb_under_panic+0x13c/0x140 net/core/skbuff.c:202 +skb_push+0xf0/0x108 net/core/skbuff.c:2446 +ip6gre_header+0xbc/0x738 net/ipv6/ip6_gre.c:1384 +dev_hard_header include/linux/netdevice.h:3136 [inline] +lapbeth_data_transmit+0x1c4/0x298 drivers/net/wan/lapbether.c:257 +lapb_data_transmit+0x8c/0xb0 net/lapb/lapb_iface.c:447 +lapb_transmit_buffer+0x178/0x204 net/lapb/lapb_out.c:149 +lapb_send_control+0x220/0x320 net/lapb/lapb_subr.c:251 +__lapb_disconnect_request+0x9c/0x17c net/lapb/lapb_iface.c:326 +lapb_device_event+0x288/0x4e0 net/lapb/lapb_iface.c:492 +notifier_call_chain+0x1a4/0x510 kernel/notifier.c:93 +raw_notifier_call_chain+0x3c/0x50 kernel/notifier.c:461 +call_netdevice_notifiers_info net/core/dev.c:1970 [inline] +call_netdevice_notifiers_extack net/core/dev.c:2008 [inline] +call_netdevice_notifiers net/core/dev.c:2022 [inline] +__dev_close_many+0x1b8/0x3c4 net/core/dev.c:1508 +dev_close_many+0x1e0/0x470 net/core/dev.c:1559 +dev_close+0x174/0x250 net/core/dev.c:1585 +lapbeth_device_event+0x2e4/0x958 drivers/net/wan/lapbether.c:466 +notifier_call_chain+0x1a4/0x510 kernel/notifier.c:93 +raw_notifier_call_chain+0x3c/0x50 kernel/notifier.c:461 +call_netdevice_notifiers_info net/core/dev.c:1970 [inline] +call_netdevice_notifiers_extack net/core/dev.c:2008 [inline] +call_netdevice_notifiers net/core/dev.c:2022 [inline] +__dev_close_many+0x1b8/0x3c4 net/core/dev.c:1508 +dev_close_many+0x1e0/0x470 net/core/dev.c:1559 +dev_close+0x174/0x250 net/core/dev.c:1585 +bond_enslave+0x2298/0x30cc drivers/net/bonding/bond_main.c:2332 +bond_do_ioctl+0x268/0xc64 drivers/net/bonding/bond_main.c:4539 +dev_ifsioc+0x754/0x9ac +dev_ioctl+0x4d8/0xd34 net/core/dev_ioctl.c:786 +sock_do_ioctl+0x1d4/0x2d0 net/socket.c:1217 +sock_ioctl+0x4e8/0x834 net/socket.c:1322 +vfs_ioctl fs/ioctl.c:51 [inline] +__do_sys_ioctl fs/ioctl.c:871 [inline] +__se_sys_ioctl fs/ioctl.c:857 [inline] +__arm64_sys_ioctl+0x14c/0x1c8 fs/ioctl.c:857 +__invoke_syscall arch/arm64/kernel/syscall.c:37 [inline] +invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:51 +el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:136 +do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:155 +el0_svc+0x58/0x16c arch/arm64/kernel/entry-common.c:678 +el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:696 +el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:591 +Code: aa1803e6 aa1903e7 a90023f5 94785b8b (d4210000) + +Fixes: 872254dd6b1f ("net/bonding: Enable bonding to enslave non ARPHRD_ETHER") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Acked-by: Jay Vosburgh +Reviewed-by: Hangbin Liu +Link: https://lore.kernel.org/r/20231109180102.4085183-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index a64ebb7f5b712..363b6cb33ae08 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1499,6 +1499,10 @@ static void bond_compute_features(struct bonding *bond) + static void bond_setup_by_slave(struct net_device *bond_dev, + struct net_device *slave_dev) + { ++ bool was_up = !!(bond_dev->flags & IFF_UP); ++ ++ dev_close(bond_dev); ++ + bond_dev->header_ops = slave_dev->header_ops; + + bond_dev->type = slave_dev->type; +@@ -1513,6 +1517,8 @@ static void bond_setup_by_slave(struct net_device *bond_dev, + bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); + } ++ if (was_up) ++ dev_open(bond_dev, NULL); + } + + /* On bonding slaves other than the currently active slave, suppress +-- +2.42.0 + diff --git a/queue-6.5/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch b/queue-6.5/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch new file mode 100644 index 00000000000..46a36fbe435 --- /dev/null +++ b/queue-6.5/bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch @@ -0,0 +1,97 @@ +From ab9ffd0d5829b1e55d195d1fbd5dd1ccc9370edb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 01:32:08 +0200 +Subject: bpf: Detect IP == ksym.end as part of BPF program + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 66d9111f3517f85ef2af0337ece02683ce0faf21 ] + +Now that bpf_throw kfunc is the first such call instruction that has +noreturn semantics within the verifier, this also kicks in dead code +elimination in unprecedented ways. For one, any instruction following +a bpf_throw call will never be marked as seen. Moreover, if a callchain +ends up throwing, any instructions after the call instruction to the +eventually throwing subprog in callers will also never be marked as +seen. + +The tempting way to fix this would be to emit extra 'int3' instructions +which bump the jited_len of a program, and ensure that during runtime +when a program throws, we can discover its boundaries even if the call +instruction to bpf_throw (or to subprogs that always throw) is emitted +as the final instruction in the program. + +An example of such a program would be this: + +do_something(): + ... + r0 = 0 + exit + +foo(): + r1 = 0 + call bpf_throw + r0 = 0 + exit + +bar(cond): + if r1 != 0 goto pc+2 + call do_something + exit + call foo + r0 = 0 // Never seen by verifier + exit // + +main(ctx): + r1 = ... + call bar + r0 = 0 + exit + +Here, if we do end up throwing, the stacktrace would be the following: + +bpf_throw +foo +bar +main + +In bar, the final instruction emitted will be the call to foo, as such, +the return address will be the subsequent instruction (which the JIT +emits as int3 on x86). This will end up lying outside the jited_len of +the program, thus, when unwinding, we will fail to discover the return +address as belonging to any program and end up in a panic due to the +unreliable stack unwinding of BPF programs that we never expect. + +To remedy this case, make bpf_prog_ksym_find treat IP == ksym.end as +part of the BPF program, so that is_bpf_text_address returns true when +such a case occurs, and we are able to unwind reliably when the final +instruction ends up being a call instruction. + +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20230912233214.1518551-12-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/core.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index e3e45b651cd40..33d1a76b7fc5d 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -613,7 +613,11 @@ static __always_inline int bpf_tree_comp(void *key, struct latch_tree_node *n) + + if (val < ksym->start) + return -1; +- if (val >= ksym->end) ++ /* Ensure that we detect return addresses as part of the program, when ++ * the final instruction is a call for a program part of the stack ++ * trace. Therefore, do val > ksym->end instead of val >= ksym->end. ++ */ ++ if (val > ksym->end) + return 1; + + return 0; +-- +2.42.0 + diff --git a/queue-6.5/bpf-ensure-proper-register-state-printing-for-cond-j.patch b/queue-6.5/bpf-ensure-proper-register-state-printing-for-cond-j.patch new file mode 100644 index 00000000000..78b37501fe0 --- /dev/null +++ b/queue-6.5/bpf-ensure-proper-register-state-printing-for-cond-j.patch @@ -0,0 +1,113 @@ +From 298c7df1e34b3d1a31aa9cf0e913311d59bf2829 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 15:37:28 -0700 +Subject: bpf: Ensure proper register state printing for cond jumps + +From: Andrii Nakryiko + +[ Upstream commit 1a8a315f008a58f54fecb012b928aa6a494435b3 ] + +Verifier emits relevant register state involved in any given instruction +next to it after `;` to the right, if possible. Or, worst case, on the +separate line repeating instruction index. + +E.g., a nice and simple case would be: + + 2: (d5) if r0 s<= 0x0 goto pc+1 ; R0_w=0 + +But if there is some intervening extra output (e.g., precision +backtracking log) involved, we are supposed to see the state after the +precision backtrack log: + + 4: (75) if r0 s>= 0x0 goto pc+1 + mark_precise: frame0: last_idx 4 first_idx 0 subseq_idx -1 + mark_precise: frame0: regs=r0 stack= before 2: (d5) if r0 s<= 0x0 goto pc+1 + mark_precise: frame0: regs=r0 stack= before 1: (b7) r0 = 0 + 6: R0_w=0 + +First off, note that in `6: R0_w=0` instruction index corresponds to the +next instruction, not to the conditional jump instruction itself, which +is wrong and we'll get to that. + +But besides that, the above is a happy case that does work today. Yet, +if it so happens that precision backtracking had to traverse some of the +parent states, this `6: R0_w=0` state output would be missing. + +This is due to a quirk of print_verifier_state() routine, which performs +mark_verifier_state_clean(env) at the end. This marks all registers as +"non-scratched", which means that subsequent logic to print *relevant* +registers (that is, "scratched ones") fails and doesn't see anything +relevant to print and skips the output altogether. + +print_verifier_state() is used both to print instruction context, but +also to print an **entire** verifier state indiscriminately, e.g., +during precision backtracking (and in a few other situations, like +during entering or exiting subprogram). Which means if we have to print +entire parent state before getting to printing instruction context +state, instruction context is marked as clean and is omitted. + +Long story short, this is definitely not intentional. So we fix this +behavior in this patch by teaching print_verifier_state() to clear +scratch state only if it was used to print instruction state, not the +parent/callback state. This is determined by print_all option, so if +it's not set, we don't clear scratch state. This fixes missing +instruction state for these cases. + +As for the mismatched instruction index, we fix that by making sure we +call print_insn_state() early inside check_cond_jmp_op() before we +adjusted insn_idx based on jump branch taken logic. And with that we get +desired correct information: + + 9: (16) if w4 == 0x1 goto pc+9 + mark_precise: frame0: last_idx 9 first_idx 9 subseq_idx -1 + mark_precise: frame0: parent state regs=r4 stack=: R2_w=1944 R4_rw=P1 R10=fp0 + mark_precise: frame0: last_idx 8 first_idx 0 subseq_idx 9 + mark_precise: frame0: regs=r4 stack= before 8: (66) if w4 s> 0x3 goto pc+5 + mark_precise: frame0: regs=r4 stack= before 7: (b7) r4 = 1 + 9: R4=1 + +Signed-off-by: Andrii Nakryiko +Signed-off-by: Daniel Borkmann +Acked-by: John Fastabend +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20231011223728.3188086-6-andrii@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index e7e2687c35884..c3b6f282128bf 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1513,7 +1513,8 @@ static void print_verifier_state(struct bpf_verifier_env *env, + if (state->in_async_callback_fn) + verbose(env, " async_cb"); + verbose(env, "\n"); +- mark_verifier_state_clean(env); ++ if (!print_all) ++ mark_verifier_state_clean(env); + } + + static inline u32 vlog_alignment(u32 pos) +@@ -13915,6 +13916,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, + !sanitize_speculative_path(env, insn, *insn_idx + 1, + *insn_idx)) + return -EFAULT; ++ if (env->log.level & BPF_LOG_LEVEL) ++ print_insn_state(env, this_branch->frame[this_branch->curframe]); + *insn_idx += insn->off; + return 0; + } else if (pred == 0) { +@@ -13927,6 +13930,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, + *insn_idx + insn->off + 1, + *insn_idx)) + return -EFAULT; ++ if (env->log.level & BPF_LOG_LEVEL) ++ print_insn_state(env, this_branch->frame[this_branch->curframe]); + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.5/bpf-fix-precision-backtracking-instruction-iteration.patch b/queue-6.5/bpf-fix-precision-backtracking-instruction-iteration.patch new file mode 100644 index 00000000000..78f7bf10028 --- /dev/null +++ b/queue-6.5/bpf-fix-precision-backtracking-instruction-iteration.patch @@ -0,0 +1,90 @@ +From dcfbbc8f9fc1a7457f3bb72ea3a11828858b6cef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 16:26:37 -0800 +Subject: bpf: fix precision backtracking instruction iteration + +From: Andrii Nakryiko + +[ Upstream commit 4bb7ea946a370707315ab774432963ce47291946 ] + +Fix an edge case in __mark_chain_precision() which prematurely stops +backtracking instructions in a state if it happens that state's first +and last instruction indexes are the same. This situations doesn't +necessarily mean that there were no instructions simulated in a state, +but rather that we starting from the instruction, jumped around a bit, +and then ended up at the same instruction before checkpointing or +marking precision. + +To distinguish between these two possible situations, we need to consult +jump history. If it's empty or contain a single record "bridging" parent +state and first instruction of processed state, then we indeed +backtracked all instructions in this state. But if history is not empty, +we are definitely not done yet. + +Move this logic inside get_prev_insn_idx() to contain it more nicely. +Use -ENOENT return code to denote "we are out of instructions" +situation. + +This bug was exposed by verifier_loop1.c's bounded_recursion subtest, once +the next fix in this patch set is applied. + +Acked-by: Eduard Zingerman +Fixes: b5dc0163d8fd ("bpf: precise scalar_value tracking") +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20231110002638.4168352-3-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index cb5621000993e..b8371feabdbdd 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3193,12 +3193,29 @@ static int push_jmp_history(struct bpf_verifier_env *env, + + /* Backtrack one insn at a time. If idx is not at the top of recorded + * history then previous instruction came from straight line execution. ++ * Return -ENOENT if we exhausted all instructions within given state. ++ * ++ * It's legal to have a bit of a looping with the same starting and ending ++ * insn index within the same state, e.g.: 3->4->5->3, so just because current ++ * instruction index is the same as state's first_idx doesn't mean we are ++ * done. If there is still some jump history left, we should keep going. We ++ * need to take into account that we might have a jump history between given ++ * state's parent and itself, due to checkpointing. In this case, we'll have ++ * history entry recording a jump from last instruction of parent state and ++ * first instruction of given state. + */ + static int get_prev_insn_idx(struct bpf_verifier_state *st, int i, + u32 *history) + { + u32 cnt = *history; + ++ if (i == st->first_insn_idx) { ++ if (cnt == 0) ++ return -ENOENT; ++ if (cnt == 1 && st->jmp_history[0].idx == i) ++ return -ENOENT; ++ } ++ + if (cnt && st->jmp_history[cnt - 1].idx == i) { + i = st->jmp_history[cnt - 1].prev_idx; + (*history)--; +@@ -4073,10 +4090,10 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno) + * Nothing to be tracked further in the parent state. + */ + return 0; +- if (i == first_idx) +- break; + subseq_idx = i; + i = get_prev_insn_idx(st, i, &history); ++ if (i == -ENOENT) ++ break; + if (i >= env->prog->len) { + /* This can happen if backtracking reached insn 0 + * and there are still reg_mask or stack_mask +-- +2.42.0 + diff --git a/queue-6.5/bpf-handle-ldimm64-properly-in-check_cfg.patch b/queue-6.5/bpf-handle-ldimm64-properly-in-check_cfg.patch new file mode 100644 index 00000000000..f617fc69f90 --- /dev/null +++ b/queue-6.5/bpf-handle-ldimm64-properly-in-check_cfg.patch @@ -0,0 +1,153 @@ +From 1d9f3757835cdab41f3080c087a2666aa3ee54b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 16:26:36 -0800 +Subject: bpf: handle ldimm64 properly in check_cfg() + +From: Andrii Nakryiko + +[ Upstream commit 3feb263bb516ee7e1da0acd22b15afbb9a7daa19 ] + +ldimm64 instructions are 16-byte long, and so have to be handled +appropriately in check_cfg(), just like the rest of BPF verifier does. + +This has implications in three places: + - when determining next instruction for non-jump instructions; + - when determining next instruction for callback address ldimm64 + instructions (in visit_func_call_insn()); + - when checking for unreachable instructions, where second half of + ldimm64 is expected to be unreachable; + +We take this also as an opportunity to report jump into the middle of +ldimm64. And adjust few test_verifier tests accordingly. + +Acked-by: Eduard Zingerman +Reported-by: Hao Sun +Fixes: 475fb78fbf48 ("bpf: verifier (add branch/goto checks)") +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20231110002638.4168352-2-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/bpf.h | 8 ++++-- + kernel/bpf/verifier.c | 27 ++++++++++++++----- + .../testing/selftests/bpf/verifier/ld_imm64.c | 8 +++--- + 3 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/include/linux/bpf.h b/include/linux/bpf.h +index 98a7d6fd10360..a8b775e9d4d1a 100644 +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -890,10 +890,14 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux *aux, u32 size) + aux->ctx_field_size = size; + } + ++static bool bpf_is_ldimm64(const struct bpf_insn *insn) ++{ ++ return insn->code == (BPF_LD | BPF_IMM | BPF_DW); ++} ++ + static inline bool bpf_pseudo_func(const struct bpf_insn *insn) + { +- return insn->code == (BPF_LD | BPF_IMM | BPF_DW) && +- insn->src_reg == BPF_PSEUDO_FUNC; ++ return bpf_is_ldimm64(insn) && insn->src_reg == BPF_PSEUDO_FUNC; + } + + struct bpf_prog_ops { +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index c3b6f282128bf..cb5621000993e 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -14563,15 +14563,16 @@ static int visit_func_call_insn(int t, struct bpf_insn *insns, + struct bpf_verifier_env *env, + bool visit_callee) + { +- int ret; ++ int ret, insn_sz; + +- ret = push_insn(t, t + 1, FALLTHROUGH, env, false); ++ insn_sz = bpf_is_ldimm64(&insns[t]) ? 2 : 1; ++ ret = push_insn(t, t + insn_sz, FALLTHROUGH, env, false); + if (ret) + return ret; + +- mark_prune_point(env, t + 1); ++ mark_prune_point(env, t + insn_sz); + /* when we exit from subprog, we need to record non-linear history */ +- mark_jmp_point(env, t + 1); ++ mark_jmp_point(env, t + insn_sz); + + if (visit_callee) { + mark_prune_point(env, t); +@@ -14593,15 +14594,17 @@ static int visit_func_call_insn(int t, struct bpf_insn *insns, + static int visit_insn(int t, struct bpf_verifier_env *env) + { + struct bpf_insn *insns = env->prog->insnsi, *insn = &insns[t]; +- int ret; ++ int ret, insn_sz; + + if (bpf_pseudo_func(insn)) + return visit_func_call_insn(t, insns, env, true); + + /* All non-branch instructions have a single fall-through edge. */ + if (BPF_CLASS(insn->code) != BPF_JMP && +- BPF_CLASS(insn->code) != BPF_JMP32) +- return push_insn(t, t + 1, FALLTHROUGH, env, false); ++ BPF_CLASS(insn->code) != BPF_JMP32) { ++ insn_sz = bpf_is_ldimm64(insn) ? 2 : 1; ++ return push_insn(t, t + insn_sz, FALLTHROUGH, env, false); ++ } + + switch (BPF_OP(insn->code)) { + case BPF_EXIT: +@@ -14715,11 +14718,21 @@ static int check_cfg(struct bpf_verifier_env *env) + } + + for (i = 0; i < insn_cnt; i++) { ++ struct bpf_insn *insn = &env->prog->insnsi[i]; ++ + if (insn_state[i] != EXPLORED) { + verbose(env, "unreachable insn %d\n", i); + ret = -EINVAL; + goto err_free; + } ++ if (bpf_is_ldimm64(insn)) { ++ if (insn_state[i + 1] != 0) { ++ verbose(env, "jump into the middle of ldimm64 insn %d\n", i); ++ ret = -EINVAL; ++ goto err_free; ++ } ++ i++; /* skip second half of ldimm64 */ ++ } + } + ret = 0; /* cfg looks good */ + +diff --git a/tools/testing/selftests/bpf/verifier/ld_imm64.c b/tools/testing/selftests/bpf/verifier/ld_imm64.c +index f9297900cea6d..78f19c255f20b 100644 +--- a/tools/testing/selftests/bpf/verifier/ld_imm64.c ++++ b/tools/testing/selftests/bpf/verifier/ld_imm64.c +@@ -9,8 +9,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 2), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid BPF_LD_IMM insn", +- .errstr_unpriv = "R1 pointer comparison", ++ .errstr = "jump into the middle of ldimm64 insn 1", ++ .errstr_unpriv = "jump into the middle of ldimm64 insn 1", + .result = REJECT, + }, + { +@@ -23,8 +23,8 @@ + BPF_LD_IMM64(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid BPF_LD_IMM insn", +- .errstr_unpriv = "R1 pointer comparison", ++ .errstr = "jump into the middle of ldimm64 insn 1", ++ .errstr_unpriv = "jump into the middle of ldimm64 insn 1", + .result = REJECT, + }, + { +-- +2.42.0 + diff --git a/queue-6.5/btrfs-abort-transaction-on-generation-mismatch-when-.patch b/queue-6.5/btrfs-abort-transaction-on-generation-mismatch-when-.patch new file mode 100644 index 00000000000..c483b368b6a --- /dev/null +++ b/queue-6.5/btrfs-abort-transaction-on-generation-mismatch-when-.patch @@ -0,0 +1,1631 @@ +From 7e5e3d81e964c99a9f9dd6fe67dd3475b0473b25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 13:04:29 +0100 +Subject: btrfs: abort transaction on generation mismatch when marking eb as + dirty + +From: Filipe Manana + +[ Upstream commit 50564b651d01c19ce732819c5b3c3fd60707188e ] + +When marking an extent buffer as dirty, at btrfs_mark_buffer_dirty(), +we check if its generation matches the running transaction and if not we +just print a warning. Such mismatch is an indicator that something really +went wrong and only printing a warning message (and stack trace) is not +enough to prevent a corruption. Allowing a transaction to commit with such +an extent buffer will trigger an error if we ever try to read it from disk +due to a generation mismatch with its parent generation. + +So abort the current transaction with -EUCLEAN if we notice a generation +mismatch. For this we need to pass a transaction handle to +btrfs_mark_buffer_dirty() which is always available except in test code, +in which case we can pass NULL since it operates on dummy extent buffers +and all test roots have a single node/leaf (root node at level 0). + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 4 +- + fs/btrfs/ctree.c | 109 +++++++++++++++------------ + fs/btrfs/ctree.h | 11 ++- + fs/btrfs/delayed-inode.c | 2 +- + fs/btrfs/dev-replace.c | 2 +- + fs/btrfs/dir-item.c | 8 +- + fs/btrfs/disk-io.c | 13 +++- + fs/btrfs/disk-io.h | 3 +- + fs/btrfs/extent-tree.c | 36 +++++---- + fs/btrfs/file-item.c | 17 +++-- + fs/btrfs/file.c | 34 ++++----- + fs/btrfs/free-space-cache.c | 6 +- + fs/btrfs/free-space-tree.c | 17 +++-- + fs/btrfs/inode-item.c | 16 ++-- + fs/btrfs/inode.c | 10 +-- + fs/btrfs/ioctl.c | 4 +- + fs/btrfs/qgroup.c | 14 ++-- + fs/btrfs/relocation.c | 10 +-- + fs/btrfs/root-tree.c | 4 +- + fs/btrfs/tests/extent-buffer-tests.c | 6 +- + fs/btrfs/tests/inode-tests.c | 12 ++- + fs/btrfs/tree-log.c | 12 +-- + fs/btrfs/uuid-tree.c | 6 +- + fs/btrfs/volumes.c | 10 +-- + fs/btrfs/xattr.c | 8 +- + 25 files changed, 205 insertions(+), 169 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 5e7a19fca79c4..bf65f801d8439 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -2587,7 +2587,7 @@ static int insert_dev_extent(struct btrfs_trans_handle *trans, + btrfs_set_dev_extent_chunk_offset(leaf, extent, chunk_offset); + + btrfs_set_dev_extent_length(leaf, extent, num_bytes); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + out: + btrfs_free_path(path); + return ret; +@@ -3011,7 +3011,7 @@ static int update_block_group_item(struct btrfs_trans_handle *trans, + cache->global_root_id); + btrfs_set_stack_block_group_flags(&bgi, cache->flags); + write_extent_buffer(leaf, &bgi, bi, sizeof(bgi)); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + fail: + btrfs_release_path(path); + /* +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 617d4827eec26..118ad4d2cbbe2 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -359,7 +359,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, + return ret; + } + +- btrfs_mark_buffer_dirty(cow); ++ btrfs_mark_buffer_dirty(trans, cow); + *cow_ret = cow; + return 0; + } +@@ -627,7 +627,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, + cow->start); + btrfs_set_node_ptr_generation(parent, parent_slot, + trans->transid); +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + if (last_ref) { + ret = btrfs_tree_mod_log_free_eb(buf); + if (ret) { +@@ -643,7 +643,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, + if (unlock_orig) + btrfs_tree_unlock(buf); + free_extent_buffer_stale(buf); +- btrfs_mark_buffer_dirty(cow); ++ btrfs_mark_buffer_dirty(trans, cow); + *cow_ret = cow; + return 0; + } +@@ -1197,7 +1197,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, + goto out; + } + btrfs_set_node_key(parent, &right_key, pslot + 1); +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + } + } + if (btrfs_header_nritems(mid) == 1) { +@@ -1255,7 +1255,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, + goto out; + } + btrfs_set_node_key(parent, &mid_key, pslot); +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + } + + /* update the path */ +@@ -1362,7 +1362,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, + return ret; + } + btrfs_set_node_key(parent, &disk_key, pslot); +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + if (btrfs_header_nritems(left) > orig_slot) { + path->nodes[level] = left; + path->slots[level + 1] -= 1; +@@ -1422,7 +1422,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, + return ret; + } + btrfs_set_node_key(parent, &disk_key, pslot + 1); +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + + if (btrfs_header_nritems(mid) <= orig_slot) { + path->nodes[level] = right; +@@ -2678,7 +2678,8 @@ int btrfs_get_next_valid_item(struct btrfs_root *root, struct btrfs_key *key, + * higher levels + * + */ +-static void fixup_low_keys(struct btrfs_path *path, ++static void fixup_low_keys(struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, + struct btrfs_disk_key *key, int level) + { + int i; +@@ -2695,7 +2696,7 @@ static void fixup_low_keys(struct btrfs_path *path, + BTRFS_MOD_LOG_KEY_REPLACE); + BUG_ON(ret < 0); + btrfs_set_node_key(t, key, tslot); +- btrfs_mark_buffer_dirty(path->nodes[i]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[i]); + if (tslot != 0) + break; + } +@@ -2707,10 +2708,11 @@ static void fixup_low_keys(struct btrfs_path *path, + * This function isn't completely safe. It's the caller's responsibility + * that the new key won't break the order + */ +-void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, ++void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + const struct btrfs_key *new_key) + { ++ struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_disk_key disk_key; + struct extent_buffer *eb; + int slot; +@@ -2748,9 +2750,9 @@ void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, + + btrfs_cpu_key_to_disk(&disk_key, new_key); + btrfs_set_item_key(eb, &disk_key, slot); +- btrfs_mark_buffer_dirty(eb); ++ btrfs_mark_buffer_dirty(trans, eb); + if (slot == 0) +- fixup_low_keys(path, &disk_key, 1); ++ fixup_low_keys(trans, path, &disk_key, 1); + } + + /* +@@ -2881,8 +2883,8 @@ static int push_node_left(struct btrfs_trans_handle *trans, + } + btrfs_set_header_nritems(src, src_nritems - push_items); + btrfs_set_header_nritems(dst, dst_nritems + push_items); +- btrfs_mark_buffer_dirty(src); +- btrfs_mark_buffer_dirty(dst); ++ btrfs_mark_buffer_dirty(trans, src); ++ btrfs_mark_buffer_dirty(trans, dst); + + return ret; + } +@@ -2957,8 +2959,8 @@ static int balance_node_right(struct btrfs_trans_handle *trans, + btrfs_set_header_nritems(src, src_nritems - push_items); + btrfs_set_header_nritems(dst, dst_nritems + push_items); + +- btrfs_mark_buffer_dirty(src); +- btrfs_mark_buffer_dirty(dst); ++ btrfs_mark_buffer_dirty(trans, src); ++ btrfs_mark_buffer_dirty(trans, dst); + + return ret; + } +@@ -3007,7 +3009,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, + + btrfs_set_node_ptr_generation(c, 0, lower_gen); + +- btrfs_mark_buffer_dirty(c); ++ btrfs_mark_buffer_dirty(trans, c); + + old = root->node; + ret = btrfs_tree_mod_log_insert_root(root->node, c, false); +@@ -3079,7 +3081,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, + WARN_ON(trans->transid == 0); + btrfs_set_node_ptr_generation(lower, slot, trans->transid); + btrfs_set_header_nritems(lower, nritems + 1); +- btrfs_mark_buffer_dirty(lower); ++ btrfs_mark_buffer_dirty(trans, lower); + + return 0; + } +@@ -3158,8 +3160,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans, + btrfs_set_header_nritems(split, c_nritems - mid); + btrfs_set_header_nritems(c, mid); + +- btrfs_mark_buffer_dirty(c); +- btrfs_mark_buffer_dirty(split); ++ btrfs_mark_buffer_dirty(trans, c); ++ btrfs_mark_buffer_dirty(trans, split); + + ret = insert_ptr(trans, path, &disk_key, split->start, + path->slots[level + 1] + 1, level + 1); +@@ -3325,15 +3327,15 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, + btrfs_set_header_nritems(left, left_nritems); + + if (left_nritems) +- btrfs_mark_buffer_dirty(left); ++ btrfs_mark_buffer_dirty(trans, left); + else + btrfs_clear_buffer_dirty(trans, left); + +- btrfs_mark_buffer_dirty(right); ++ btrfs_mark_buffer_dirty(trans, right); + + btrfs_item_key(right, &disk_key, 0); + btrfs_set_node_key(upper, &disk_key, slot + 1); +- btrfs_mark_buffer_dirty(upper); ++ btrfs_mark_buffer_dirty(trans, upper); + + /* then fixup the leaf pointer in the path */ + if (path->slots[0] >= left_nritems) { +@@ -3545,14 +3547,14 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, + btrfs_set_token_item_offset(&token, i, push_space); + } + +- btrfs_mark_buffer_dirty(left); ++ btrfs_mark_buffer_dirty(trans, left); + if (right_nritems) +- btrfs_mark_buffer_dirty(right); ++ btrfs_mark_buffer_dirty(trans, right); + else + btrfs_clear_buffer_dirty(trans, right); + + btrfs_item_key(right, &disk_key, 0); +- fixup_low_keys(path, &disk_key, 1); ++ fixup_low_keys(trans, path, &disk_key, 1); + + /* then fixup the leaf pointer in the path */ + if (path->slots[0] < push_items) { +@@ -3683,8 +3685,8 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans, + if (ret < 0) + return ret; + +- btrfs_mark_buffer_dirty(right); +- btrfs_mark_buffer_dirty(l); ++ btrfs_mark_buffer_dirty(trans, right); ++ btrfs_mark_buffer_dirty(trans, l); + BUG_ON(path->slots[0] != slot); + + if (mid <= slot) { +@@ -3925,7 +3927,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, + path->nodes[0] = right; + path->slots[0] = 0; + if (path->slots[1] == 0) +- fixup_low_keys(path, &disk_key, 1); ++ fixup_low_keys(trans, path, &disk_key, 1); + } + /* + * We create a new leaf 'right' for the required ins_len and +@@ -4024,7 +4026,8 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, + return ret; + } + +-static noinline int split_item(struct btrfs_path *path, ++static noinline int split_item(struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, + const struct btrfs_key *new_key, + unsigned long split_offset) + { +@@ -4083,7 +4086,7 @@ static noinline int split_item(struct btrfs_path *path, + write_extent_buffer(leaf, buf + split_offset, + btrfs_item_ptr_offset(leaf, slot), + item_size - split_offset); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + BUG_ON(btrfs_leaf_free_space(leaf) < 0); + kfree(buf); +@@ -4117,7 +4120,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, + if (ret) + return ret; + +- ret = split_item(path, new_key, split_offset); ++ ret = split_item(trans, path, new_key, split_offset); + return ret; + } + +@@ -4127,7 +4130,8 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, + * off the end of the item or if we shift the item to chop bytes off + * the front. + */ +-void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) ++void btrfs_truncate_item(struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, u32 new_size, int from_end) + { + int slot; + struct extent_buffer *leaf; +@@ -4203,11 +4207,11 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) + btrfs_set_disk_key_offset(&disk_key, offset + size_diff); + btrfs_set_item_key(leaf, &disk_key, slot); + if (slot == 0) +- fixup_low_keys(path, &disk_key, 1); ++ fixup_low_keys(trans, path, &disk_key, 1); + } + + btrfs_set_item_size(leaf, slot, new_size); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + if (btrfs_leaf_free_space(leaf) < 0) { + btrfs_print_leaf(leaf); +@@ -4218,7 +4222,8 @@ void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end) + /* + * make the item pointed to by the path bigger, data_size is the added size. + */ +-void btrfs_extend_item(struct btrfs_path *path, u32 data_size) ++void btrfs_extend_item(struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, u32 data_size) + { + int slot; + struct extent_buffer *leaf; +@@ -4268,7 +4273,7 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) + data_end = old_data; + old_size = btrfs_item_size(leaf, slot); + btrfs_set_item_size(leaf, slot, old_size + data_size); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + if (btrfs_leaf_free_space(leaf) < 0) { + btrfs_print_leaf(leaf); +@@ -4279,6 +4284,7 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) + /* + * Make space in the node before inserting one or more items. + * ++ * @trans: transaction handle + * @root: root we are inserting items to + * @path: points to the leaf/slot where we are going to insert new items + * @batch: information about the batch of items to insert +@@ -4286,7 +4292,8 @@ void btrfs_extend_item(struct btrfs_path *path, u32 data_size) + * Main purpose is to save stack depth by doing the bulk of the work in a + * function that doesn't call btrfs_search_slot + */ +-static void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *path, ++static void setup_items_for_insert(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, struct btrfs_path *path, + const struct btrfs_item_batch *batch) + { + struct btrfs_fs_info *fs_info = root->fs_info; +@@ -4306,7 +4313,7 @@ static void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *p + */ + if (path->slots[0] == 0) { + btrfs_cpu_key_to_disk(&disk_key, &batch->keys[0]); +- fixup_low_keys(path, &disk_key, 1); ++ fixup_low_keys(trans, path, &disk_key, 1); + } + btrfs_unlock_up_safe(path, 1); + +@@ -4365,7 +4372,7 @@ static void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *p + } + + btrfs_set_header_nritems(leaf, nritems + batch->nr); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + if (btrfs_leaf_free_space(leaf) < 0) { + btrfs_print_leaf(leaf); +@@ -4376,12 +4383,14 @@ static void setup_items_for_insert(struct btrfs_root *root, struct btrfs_path *p + /* + * Insert a new item into a leaf. + * ++ * @trans: Transaction handle. + * @root: The root of the btree. + * @path: A path pointing to the target leaf and slot. + * @key: The key of the new item. + * @data_size: The size of the data associated with the new key. + */ +-void btrfs_setup_item_for_insert(struct btrfs_root *root, ++void btrfs_setup_item_for_insert(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_key *key, + u32 data_size) +@@ -4393,7 +4402,7 @@ void btrfs_setup_item_for_insert(struct btrfs_root *root, + batch.total_data_size = data_size; + batch.nr = 1; + +- setup_items_for_insert(root, path, &batch); ++ setup_items_for_insert(trans, root, path, &batch); + } + + /* +@@ -4419,7 +4428,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, + slot = path->slots[0]; + BUG_ON(slot < 0); + +- setup_items_for_insert(root, path, batch); ++ setup_items_for_insert(trans, root, path, batch); + return 0; + } + +@@ -4444,7 +4453,7 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, + leaf = path->nodes[0]; + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); + write_extent_buffer(leaf, data, ptr, data_size); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } + btrfs_free_path(path); + return ret; +@@ -4475,7 +4484,7 @@ int btrfs_duplicate_item(struct btrfs_trans_handle *trans, + return ret; + + path->slots[0]++; +- btrfs_setup_item_for_insert(root, path, new_key, item_size); ++ btrfs_setup_item_for_insert(trans, root, path, new_key, item_size); + leaf = path->nodes[0]; + memcpy_extent_buffer(leaf, + btrfs_item_ptr_offset(leaf, path->slots[0]), +@@ -4533,9 +4542,9 @@ int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_disk_key disk_key; + + btrfs_node_key(parent, &disk_key, 0); +- fixup_low_keys(path, &disk_key, level + 1); ++ fixup_low_keys(trans, path, &disk_key, level + 1); + } +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + return 0; + } + +@@ -4632,7 +4641,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_disk_key disk_key; + + btrfs_item_key(leaf, &disk_key, 0); +- fixup_low_keys(path, &disk_key, 1); ++ fixup_low_keys(trans, path, &disk_key, 1); + } + + /* +@@ -4697,11 +4706,11 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + * dirtied this buffer + */ + if (path->nodes[0] == leaf) +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + free_extent_buffer(leaf); + } + } else { +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } + } + return ret; +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index ff40acd63a374..06333a74d6c4c 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -518,7 +518,7 @@ int btrfs_previous_item(struct btrfs_root *root, + int type); + int btrfs_previous_extent_item(struct btrfs_root *root, + struct btrfs_path *path, u64 min_objectid); +-void btrfs_set_item_key_safe(struct btrfs_fs_info *fs_info, ++void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + const struct btrfs_key *new_key); + struct extent_buffer *btrfs_root_node(struct btrfs_root *root); +@@ -545,8 +545,10 @@ int btrfs_block_can_be_shared(struct btrfs_trans_handle *trans, + struct extent_buffer *buf); + int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot); +-void btrfs_extend_item(struct btrfs_path *path, u32 data_size); +-void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); ++void btrfs_extend_item(struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, u32 data_size); ++void btrfs_truncate_item(struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, u32 new_size, int from_end); + int btrfs_split_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, +@@ -610,7 +612,8 @@ struct btrfs_item_batch { + int nr; + }; + +-void btrfs_setup_item_for_insert(struct btrfs_root *root, ++void btrfs_setup_item_for_insert(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, + struct btrfs_path *path, + const struct btrfs_key *key, + u32 data_size); +diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c +index 142e0a0f6a9fe..5d3229b42b3e2 100644 +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -1030,7 +1030,7 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, + struct btrfs_inode_item); + write_extent_buffer(leaf, &node->inode_item, (unsigned long)inode_item, + sizeof(struct btrfs_inode_item)); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + if (!test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags)) + goto out; +diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c +index 5f10965fd72bf..5549cbd9bdf6a 100644 +--- a/fs/btrfs/dev-replace.c ++++ b/fs/btrfs/dev-replace.c +@@ -442,7 +442,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans) + dev_replace->item_needs_writeback = 0; + up_write(&dev_replace->rwsem); + +- btrfs_mark_buffer_dirty(eb); ++ btrfs_mark_buffer_dirty(trans, eb); + + out: + btrfs_free_path(path); +diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c +index 082eb0e195981..9c07d5c3e5ad2 100644 +--- a/fs/btrfs/dir-item.c ++++ b/fs/btrfs/dir-item.c +@@ -38,7 +38,7 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle + di = btrfs_match_dir_item_name(fs_info, path, name, name_len); + if (di) + return ERR_PTR(-EEXIST); +- btrfs_extend_item(path, data_size); ++ btrfs_extend_item(trans, path, data_size); + } else if (ret < 0) + return ERR_PTR(ret); + WARN_ON(ret > 0); +@@ -93,7 +93,7 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, + + write_extent_buffer(leaf, name, name_ptr, name_len); + write_extent_buffer(leaf, data, data_ptr, data_len); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + + return ret; + } +@@ -153,7 +153,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, + name_ptr = (unsigned long)(dir_item + 1); + + write_extent_buffer(leaf, name->name, name_ptr, name->len); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + second_insert: + /* FIXME, use some real flag for selecting the extra index */ +@@ -439,7 +439,7 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, + start = btrfs_item_ptr_offset(leaf, path->slots[0]); + memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, + item_len - (ptr + sub_item_len - start)); +- btrfs_truncate_item(path, item_len - sub_item_len, 1); ++ btrfs_truncate_item(trans, path, item_len - sub_item_len, 1); + } + return ret; + } +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 681594df7334f..1ae781f533582 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -872,7 +872,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, + } + + root->node = leaf; +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + root->commit_root = btrfs_root_node(root); + set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state); +@@ -947,7 +947,7 @@ int btrfs_alloc_log_tree_node(struct btrfs_trans_handle *trans, + + root->node = leaf; + +- btrfs_mark_buffer_dirty(root->node); ++ btrfs_mark_buffer_dirty(trans, root->node); + btrfs_tree_unlock(root->node); + + return 0; +@@ -4426,7 +4426,8 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) + btrfs_close_devices(fs_info->fs_devices); + } + +-void btrfs_mark_buffer_dirty(struct extent_buffer *buf) ++void btrfs_mark_buffer_dirty(struct btrfs_trans_handle *trans, ++ struct extent_buffer *buf) + { + struct btrfs_fs_info *fs_info = buf->fs_info; + u64 transid = btrfs_header_generation(buf); +@@ -4440,10 +4441,14 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) + if (unlikely(test_bit(EXTENT_BUFFER_UNMAPPED, &buf->bflags))) + return; + #endif ++ /* This is an active transaction (its state < TRANS_STATE_UNBLOCKED). */ ++ ASSERT(trans->transid == fs_info->generation); + btrfs_assert_tree_write_locked(buf); +- if (transid != fs_info->generation) ++ if (transid != fs_info->generation) { + WARN(1, KERN_CRIT "btrfs transid mismatch buffer %llu, found %llu running %llu\n", + buf->start, transid, fs_info->generation); ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ } + set_extent_buffer_dirty(buf); + #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY + /* +diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h +index b03767f4d7edf..e5bdb96912438 100644 +--- a/fs/btrfs/disk-io.h ++++ b/fs/btrfs/disk-io.h +@@ -105,7 +105,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root) + } + + void btrfs_put_root(struct btrfs_root *root); +-void btrfs_mark_buffer_dirty(struct extent_buffer *buf); ++void btrfs_mark_buffer_dirty(struct btrfs_trans_handle *trans, ++ struct extent_buffer *buf); + int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, + int atomic); + int btrfs_read_extent_buffer(struct extent_buffer *buf, +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 14ea6b587e97b..118c56c512bd8 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -596,7 +596,7 @@ static noinline int insert_extent_data_ref(struct btrfs_trans_handle *trans, + btrfs_set_extent_data_ref_count(leaf, ref, num_refs); + } + } +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + ret = 0; + fail: + btrfs_release_path(path); +@@ -644,7 +644,7 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans, + btrfs_set_extent_data_ref_count(leaf, ref1, num_refs); + else if (key.type == BTRFS_SHARED_DATA_REF_KEY) + btrfs_set_shared_data_ref_count(leaf, ref2, num_refs); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } + return ret; + } +@@ -997,7 +997,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, + * helper to add new inline back ref + */ + static noinline_for_stack +-void setup_inline_extent_backref(struct btrfs_fs_info *fs_info, ++void setup_inline_extent_backref(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + struct btrfs_extent_inline_ref *iref, + u64 parent, u64 root_objectid, +@@ -1020,7 +1020,7 @@ void setup_inline_extent_backref(struct btrfs_fs_info *fs_info, + type = extent_ref_type(parent, owner); + size = btrfs_extent_inline_ref_size(type); + +- btrfs_extend_item(path, size); ++ btrfs_extend_item(trans, path, size); + + ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); + refs = btrfs_extent_refs(leaf, ei); +@@ -1054,7 +1054,7 @@ void setup_inline_extent_backref(struct btrfs_fs_info *fs_info, + } else { + btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid); + } +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } + + static int lookup_extent_backref(struct btrfs_trans_handle *trans, +@@ -1087,7 +1087,9 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans, + /* + * helper to update/remove inline back ref + */ +-static noinline_for_stack int update_inline_extent_backref(struct btrfs_path *path, ++static noinline_for_stack int update_inline_extent_backref( ++ struct btrfs_trans_handle *trans, ++ struct btrfs_path *path, + struct btrfs_extent_inline_ref *iref, + int refs_to_mod, + struct btrfs_delayed_extent_op *extent_op) +@@ -1195,9 +1197,9 @@ static noinline_for_stack int update_inline_extent_backref(struct btrfs_path *pa + memmove_extent_buffer(leaf, ptr, ptr + size, + end - ptr - size); + item_size -= size; +- btrfs_truncate_item(path, item_size, 1); ++ btrfs_truncate_item(trans, path, item_size, 1); + } +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + return 0; + } + +@@ -1227,9 +1229,10 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans, + bytenr, num_bytes, root_objectid, path->slots[0]); + return -EUCLEAN; + } +- ret = update_inline_extent_backref(path, iref, refs_to_add, extent_op); ++ ret = update_inline_extent_backref(trans, path, iref, ++ refs_to_add, extent_op); + } else if (ret == -ENOENT) { +- setup_inline_extent_backref(trans->fs_info, path, iref, parent, ++ setup_inline_extent_backref(trans, path, iref, parent, + root_objectid, owner, offset, + refs_to_add, extent_op); + ret = 0; +@@ -1247,7 +1250,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, + + BUG_ON(!is_data && refs_to_drop != 1); + if (iref) +- ret = update_inline_extent_backref(path, iref, -refs_to_drop, NULL); ++ ret = update_inline_extent_backref(trans, path, iref, ++ -refs_to_drop, NULL); + else if (is_data) + ret = remove_extent_data_ref(trans, root, path, refs_to_drop); + else +@@ -1531,7 +1535,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, + if (extent_op) + __run_delayed_extent_op(extent_op, leaf, item); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + /* now insert the actual backref */ +@@ -1697,7 +1701,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, + ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); + __run_delayed_extent_op(extent_op, leaf, ei); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + out: + btrfs_free_path(path); + return err; +@@ -3171,7 +3175,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, + } + } else { + btrfs_set_extent_refs(leaf, ei, refs); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } + if (found_extent) { + ret = remove_extent_backref(trans, extent_root, path, +@@ -4679,7 +4683,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, + btrfs_set_extent_data_ref_count(leaf, ref, ref_mod); + } + +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + btrfs_free_path(path); + + return alloc_reserved_extent(trans, ins->objectid, ins->offset); +@@ -4754,7 +4758,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, + btrfs_set_extent_inline_ref_offset(leaf, iref, ref->root); + } + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_free_path(path); + + return alloc_reserved_extent(trans, node->bytenr, fs_info->nodesize); +diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c +index 1ce5dd1544995..45cae356e89ba 100644 +--- a/fs/btrfs/file-item.c ++++ b/fs/btrfs/file-item.c +@@ -194,7 +194,7 @@ int btrfs_insert_hole_extent(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_encryption(leaf, item, 0); + btrfs_set_file_extent_other_encoding(leaf, item, 0); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + out: + btrfs_free_path(path); + return ret; +@@ -811,11 +811,12 @@ blk_status_t btrfs_alloc_dummy_sum(struct btrfs_bio *bbio) + * This calls btrfs_truncate_item with the correct args based on the overlap, + * and fixes up the key as required. + */ +-static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info, ++static noinline void truncate_one_csum(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + struct btrfs_key *key, + u64 bytenr, u64 len) + { ++ struct btrfs_fs_info *fs_info = trans->fs_info; + struct extent_buffer *leaf; + const u32 csum_size = fs_info->csum_size; + u64 csum_end; +@@ -836,7 +837,7 @@ static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info, + */ + u32 new_size = (bytenr - key->offset) >> blocksize_bits; + new_size *= csum_size; +- btrfs_truncate_item(path, new_size, 1); ++ btrfs_truncate_item(trans, path, new_size, 1); + } else if (key->offset >= bytenr && csum_end > end_byte && + end_byte > key->offset) { + /* +@@ -848,10 +849,10 @@ static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info, + u32 new_size = (csum_end - end_byte) >> blocksize_bits; + new_size *= csum_size; + +- btrfs_truncate_item(path, new_size, 0); ++ btrfs_truncate_item(trans, path, new_size, 0); + + key->offset = end_byte; +- btrfs_set_item_key_safe(fs_info, path, key); ++ btrfs_set_item_key_safe(trans, path, key); + } else { + BUG(); + } +@@ -994,7 +995,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + + key.offset = end_byte - 1; + } else { +- truncate_one_csum(fs_info, path, &key, bytenr, len); ++ truncate_one_csum(trans, path, &key, bytenr, len); + if (key.offset < bytenr) + break; + } +@@ -1202,7 +1203,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, + diff /= csum_size; + diff *= csum_size; + +- btrfs_extend_item(path, diff); ++ btrfs_extend_item(trans, path, diff); + ret = 0; + goto csum; + } +@@ -1249,7 +1250,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, + ins_size /= csum_size; + total_bytes += ins_size * fs_info->sectorsize; + +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + if (total_bytes < sums->len) { + btrfs_release_path(path); + cond_resched(); +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index eae9175f2c29b..a407af38a9237 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -368,7 +368,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_offset(leaf, fi, extent_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - args->start); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + if (update_refs && disk_bytenr > 0) { + btrfs_init_generic_ref(&ref, +@@ -405,13 +405,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, + + memcpy(&new_key, &key, sizeof(new_key)); + new_key.offset = args->end; +- btrfs_set_item_key_safe(fs_info, path, &new_key); ++ btrfs_set_item_key_safe(trans, path, &new_key); + + extent_offset += args->end - key.offset; + btrfs_set_file_extent_offset(leaf, fi, extent_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - args->end); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + if (update_refs && disk_bytenr > 0) + args->bytes_found += args->end - key.offset; + break; +@@ -431,7 +431,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, + + btrfs_set_file_extent_num_bytes(leaf, fi, + args->start - key.offset); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + if (update_refs && disk_bytenr > 0) + args->bytes_found += extent_end - args->start; + if (args->end == extent_end) +@@ -536,7 +536,8 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, + if (btrfs_comp_cpu_keys(&key, &slot_key) > 0) + path->slots[0]++; + } +- btrfs_setup_item_for_insert(root, path, &key, args->extent_item_size); ++ btrfs_setup_item_for_insert(trans, root, path, &key, ++ args->extent_item_size); + args->extent_inserted = true; + } + +@@ -593,7 +594,6 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot, + int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + struct btrfs_inode *inode, u64 start, u64 end) + { +- struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *root = inode->root; + struct extent_buffer *leaf; + struct btrfs_path *path; +@@ -664,7 +664,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + ino, bytenr, orig_offset, + &other_start, &other_end)) { + new_key.offset = end; +- btrfs_set_item_key_safe(fs_info, path, &new_key); ++ btrfs_set_item_key_safe(trans, path, &new_key); + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + btrfs_set_file_extent_generation(leaf, fi, +@@ -679,7 +679,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + trans->transid); + btrfs_set_file_extent_num_bytes(leaf, fi, + end - other_start); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + goto out; + } + } +@@ -698,7 +698,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + trans->transid); + path->slots[0]++; + new_key.offset = start; +- btrfs_set_item_key_safe(fs_info, path, &new_key); ++ btrfs_set_item_key_safe(trans, path, &new_key); + + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); +@@ -708,7 +708,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + other_end - start); + btrfs_set_file_extent_offset(leaf, fi, + start - orig_offset); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + goto out; + } + } +@@ -742,7 +742,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_offset(leaf, fi, split - orig_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - split); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, bytenr, + num_bytes, 0); +@@ -814,7 +814,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_type(leaf, fi, + BTRFS_FILE_EXTENT_REG); + btrfs_set_file_extent_generation(leaf, fi, trans->transid); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } else { + fi = btrfs_item_ptr(leaf, del_slot - 1, + struct btrfs_file_extent_item); +@@ -823,7 +823,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_generation(leaf, fi, trans->transid); + btrfs_set_file_extent_num_bytes(leaf, fi, + extent_end - key.offset); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + ret = btrfs_del_items(trans, root, path, del_slot, del_nr); + if (ret < 0) { +@@ -2103,7 +2103,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes); + btrfs_set_file_extent_offset(leaf, fi, 0); + btrfs_set_file_extent_generation(leaf, fi, trans->transid); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + goto out; + } + +@@ -2111,7 +2111,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, + u64 num_bytes; + + key.offset = offset; +- btrfs_set_item_key_safe(fs_info, path, &key); ++ btrfs_set_item_key_safe(trans, path, &key); + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + num_bytes = btrfs_file_extent_num_bytes(leaf, fi) + end - +@@ -2120,7 +2120,7 @@ static int fill_holes(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes); + btrfs_set_file_extent_offset(leaf, fi, 0); + btrfs_set_file_extent_generation(leaf, fi, trans->transid); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + goto out; + } + btrfs_release_path(path); +@@ -2272,7 +2272,7 @@ static int btrfs_insert_replace_extent(struct btrfs_trans_handle *trans, + btrfs_set_file_extent_num_bytes(leaf, extent, replace_len); + if (extent_info->is_new_extent) + btrfs_set_file_extent_generation(leaf, extent, trans->transid); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + ret = btrfs_inode_set_file_extent_range(inode, extent_info->file_offset, +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index 8808004180759..6b7383ae5a70c 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -195,7 +195,7 @@ static int __create_free_space_inode(struct btrfs_root *root, + btrfs_set_inode_nlink(leaf, inode_item, 1); + btrfs_set_inode_transid(leaf, inode_item, trans->transid); + btrfs_set_inode_block_group(leaf, inode_item, offset); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + key.objectid = BTRFS_FREE_SPACE_OBJECTID; +@@ -213,7 +213,7 @@ static int __create_free_space_inode(struct btrfs_root *root, + struct btrfs_free_space_header); + memzero_extent_buffer(leaf, (unsigned long)header, sizeof(*header)); + btrfs_set_free_space_key(leaf, header, &disk_key); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + return 0; +@@ -1185,7 +1185,7 @@ update_cache_item(struct btrfs_trans_handle *trans, + btrfs_set_free_space_entries(leaf, header, entries); + btrfs_set_free_space_bitmaps(leaf, header, bitmaps); + btrfs_set_free_space_generation(leaf, header, trans->transid); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + return 0; +diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c +index f169378e2ca6e..ae060a26e1191 100644 +--- a/fs/btrfs/free-space-tree.c ++++ b/fs/btrfs/free-space-tree.c +@@ -89,7 +89,7 @@ static int add_new_free_space_info(struct btrfs_trans_handle *trans, + struct btrfs_free_space_info); + btrfs_set_free_space_extent_count(leaf, info, 0); + btrfs_set_free_space_flags(leaf, info, 0); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + ret = 0; + out: +@@ -287,7 +287,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, + flags |= BTRFS_FREE_SPACE_USING_BITMAPS; + btrfs_set_free_space_flags(leaf, info, flags); + expected_extent_count = btrfs_free_space_extent_count(leaf, info); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + if (extent_count != expected_extent_count) { +@@ -324,7 +324,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); + write_extent_buffer(leaf, bitmap_cursor, ptr, + data_size); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + i += extent_size; +@@ -430,7 +430,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, + flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS; + btrfs_set_free_space_flags(leaf, info, flags); + expected_extent_count = btrfs_free_space_extent_count(leaf, info); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + nrbits = block_group->length >> block_group->fs_info->sectorsize_bits; +@@ -495,7 +495,7 @@ static int update_free_space_extent_count(struct btrfs_trans_handle *trans, + + extent_count += new_extents; + btrfs_set_free_space_extent_count(path->nodes[0], info, extent_count); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + btrfs_release_path(path); + + if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) && +@@ -533,7 +533,8 @@ int free_space_test_bit(struct btrfs_block_group *block_group, + return !!extent_buffer_test_bit(leaf, ptr, i); + } + +-static void free_space_set_bits(struct btrfs_block_group *block_group, ++static void free_space_set_bits(struct btrfs_trans_handle *trans, ++ struct btrfs_block_group *block_group, + struct btrfs_path *path, u64 *start, u64 *size, + int bit) + { +@@ -563,7 +564,7 @@ static void free_space_set_bits(struct btrfs_block_group *block_group, + extent_buffer_bitmap_set(leaf, ptr, first, last - first); + else + extent_buffer_bitmap_clear(leaf, ptr, first, last - first); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + *size -= end - *start; + *start = end; +@@ -656,7 +657,7 @@ static int modify_free_space_bitmap(struct btrfs_trans_handle *trans, + cur_start = start; + cur_size = size; + while (1) { +- free_space_set_bits(block_group, path, &cur_start, &cur_size, ++ free_space_set_bits(trans, block_group, path, &cur_start, &cur_size, + !remove); + if (cur_size == 0) + break; +diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c +index 4c322b720a80a..d3ff97374d48a 100644 +--- a/fs/btrfs/inode-item.c ++++ b/fs/btrfs/inode-item.c +@@ -167,7 +167,7 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans, + memmove_extent_buffer(leaf, ptr, ptr + del_len, + item_size - (ptr + del_len - item_start)); + +- btrfs_truncate_item(path, item_size - del_len, 1); ++ btrfs_truncate_item(trans, path, item_size - del_len, 1); + + out: + btrfs_free_path(path); +@@ -229,7 +229,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, + item_start = btrfs_item_ptr_offset(leaf, path->slots[0]); + memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, + item_size - (ptr + sub_item_len - item_start)); +- btrfs_truncate_item(path, item_size - sub_item_len, 1); ++ btrfs_truncate_item(trans, path, item_size - sub_item_len, 1); + out: + btrfs_free_path(path); + +@@ -282,7 +282,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, + name)) + goto out; + +- btrfs_extend_item(path, ins_len); ++ btrfs_extend_item(trans, path, ins_len); + ret = 0; + } + if (ret < 0) +@@ -299,7 +299,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, + + ptr = (unsigned long)&extref->name; + write_extent_buffer(path->nodes[0], name->name, ptr, name->len); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + + out: + btrfs_free_path(path); +@@ -338,7 +338,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, + goto out; + + old_size = btrfs_item_size(path->nodes[0], path->slots[0]); +- btrfs_extend_item(path, ins_len); ++ btrfs_extend_item(trans, path, ins_len); + ref = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_inode_ref); + ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); +@@ -364,7 +364,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, + ptr = (unsigned long)(ref + 1); + } + write_extent_buffer(path->nodes[0], name->name, ptr, name->len); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + + out: + btrfs_free_path(path); +@@ -591,7 +591,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, + num_dec = (orig_num_bytes - extent_num_bytes); + if (extent_start != 0) + control->sub_bytes += num_dec; +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } else { + extent_num_bytes = + btrfs_file_extent_disk_num_bytes(leaf, fi); +@@ -617,7 +617,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, + + btrfs_set_file_extent_ram_bytes(leaf, fi, size); + size = btrfs_file_extent_calc_inline_size(size); +- btrfs_truncate_item(path, size, 1); ++ btrfs_truncate_item(trans, path, size, 1); + } else if (!del_item) { + /* + * We have to bail so the last_size is set to +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 0f4498dfa30c9..58e104f118f96 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -573,7 +573,7 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, + kunmap_local(kaddr); + put_page(page); + } +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + /* +@@ -3072,7 +3072,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, + btrfs_item_ptr_offset(leaf, path->slots[0]), + sizeof(struct btrfs_file_extent_item)); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_release_path(path); + + /* +@@ -4134,7 +4134,7 @@ static noinline int btrfs_update_inode_item(struct btrfs_trans_handle *trans, + struct btrfs_inode_item); + + fill_inode_item(trans, leaf, inode_item, &inode->vfs_inode); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_set_inode_last_trans(trans, inode); + ret = 0; + failed: +@@ -6476,7 +6476,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, + } + } + +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + /* + * We don't need the path anymore, plus inheriting properties, adding + * ACLs, security xattrs, orphan item or adding the link, will result in +@@ -9630,7 +9630,7 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, + + ptr = btrfs_file_extent_inline_start(ei); + write_extent_buffer(leaf, symname, ptr, name_len); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + btrfs_free_path(path); + + d_instantiate_new(dentry, inode); +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 6d0df9bc1e72b..8bdf9bed25c75 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -663,7 +663,7 @@ static noinline int create_subvol(struct mnt_idmap *idmap, + goto out; + } + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + inode_item = &root_item->inode; + btrfs_set_stack_inode_generation(inode_item, 1); +@@ -2947,7 +2947,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) + + btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key); + btrfs_set_dir_item_key(path->nodes[0], di, &disk_key); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + btrfs_release_path(path); + + btrfs_set_fs_incompat(fs_info, DEFAULT_SUBVOL); +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 2637d6b157ff9..74cabaa59be71 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -622,7 +622,7 @@ static int add_qgroup_relation_item(struct btrfs_trans_handle *trans, u64 src, + + ret = btrfs_insert_empty_item(trans, quota_root, path, &key, 0); + +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + + btrfs_free_path(path); + return ret; +@@ -700,7 +700,7 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans, + btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0); + btrfs_set_qgroup_info_excl_cmpr(leaf, qgroup_info, 0); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + btrfs_release_path(path); + +@@ -719,7 +719,7 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans, + btrfs_set_qgroup_limit_rsv_rfer(leaf, qgroup_limit, 0); + btrfs_set_qgroup_limit_rsv_excl(leaf, qgroup_limit, 0); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + ret = 0; + out: +@@ -808,7 +808,7 @@ static int update_qgroup_limit_item(struct btrfs_trans_handle *trans, + btrfs_set_qgroup_limit_rsv_rfer(l, qgroup_limit, qgroup->rsv_rfer); + btrfs_set_qgroup_limit_rsv_excl(l, qgroup_limit, qgroup->rsv_excl); + +- btrfs_mark_buffer_dirty(l); ++ btrfs_mark_buffer_dirty(trans, l); + + out: + btrfs_free_path(path); +@@ -854,7 +854,7 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans, + btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl); + btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr); + +- btrfs_mark_buffer_dirty(l); ++ btrfs_mark_buffer_dirty(trans, l); + + out: + btrfs_free_path(path); +@@ -896,7 +896,7 @@ static int update_qgroup_status_item(struct btrfs_trans_handle *trans) + btrfs_set_qgroup_status_rescan(l, ptr, + fs_info->qgroup_rescan_progress.objectid); + +- btrfs_mark_buffer_dirty(l); ++ btrfs_mark_buffer_dirty(trans, l); + + out: + btrfs_free_path(path); +@@ -1069,7 +1069,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) + BTRFS_QGROUP_STATUS_FLAGS_MASK); + btrfs_set_qgroup_status_rescan(leaf, ptr, 0); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + key.objectid = 0; + key.type = BTRFS_ROOT_REF_KEY; +diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c +index 62ed57551824c..31781af447553 100644 +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -1181,7 +1181,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans, + } + } + if (dirty) +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + if (inode) + btrfs_add_delayed_iput(BTRFS_I(inode)); + return ret; +@@ -1374,13 +1374,13 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, + */ + btrfs_set_node_blockptr(parent, slot, new_bytenr); + btrfs_set_node_ptr_generation(parent, slot, new_ptr_gen); +- btrfs_mark_buffer_dirty(parent); ++ btrfs_mark_buffer_dirty(trans, parent); + + btrfs_set_node_blockptr(path->nodes[level], + path->slots[level], old_bytenr); + btrfs_set_node_ptr_generation(path->nodes[level], + path->slots[level], old_ptr_gen); +- btrfs_mark_buffer_dirty(path->nodes[level]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[level]); + + btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, old_bytenr, + blocksize, path->nodes[level]->start); +@@ -2517,7 +2517,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, + node->eb->start); + btrfs_set_node_ptr_generation(upper->eb, slot, + trans->transid); +- btrfs_mark_buffer_dirty(upper->eb); ++ btrfs_mark_buffer_dirty(trans, upper->eb); + + btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, + node->eb->start, blocksize, +@@ -3833,7 +3833,7 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans, + btrfs_set_inode_mode(leaf, item, S_IFREG | 0600); + btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS | + BTRFS_INODE_PREALLOC); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + out: + btrfs_free_path(path); + return ret; +diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c +index 859874579456f..5b0f1bccc409c 100644 +--- a/fs/btrfs/root-tree.c ++++ b/fs/btrfs/root-tree.c +@@ -191,7 +191,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root + btrfs_set_root_generation_v2(item, btrfs_root_generation(item)); + + write_extent_buffer(l, item, ptr, sizeof(*item)); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + out: + btrfs_free_path(path); + return ret; +@@ -438,7 +438,7 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id, + btrfs_set_root_ref_name_len(leaf, ref, name->len); + ptr = (unsigned long)(ref + 1); + write_extent_buffer(leaf, name->name, ptr, name->len); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + if (key.type == BTRFS_ROOT_BACKREF_KEY) { + btrfs_release_path(path); +diff --git a/fs/btrfs/tests/extent-buffer-tests.c b/fs/btrfs/tests/extent-buffer-tests.c +index 5ef0b90e25c3b..6a43a64ba55ad 100644 +--- a/fs/btrfs/tests/extent-buffer-tests.c ++++ b/fs/btrfs/tests/extent-buffer-tests.c +@@ -61,7 +61,11 @@ static int test_btrfs_split_item(u32 sectorsize, u32 nodesize) + key.type = BTRFS_EXTENT_CSUM_KEY; + key.offset = 0; + +- btrfs_setup_item_for_insert(root, path, &key, value_len); ++ /* ++ * Passing a NULL trans handle is fine here, we have a dummy root eb ++ * and the tree is a single node (level 0). ++ */ ++ btrfs_setup_item_for_insert(NULL, root, path, &key, value_len); + write_extent_buffer(eb, value, btrfs_item_ptr_offset(eb, 0), + value_len); + +diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c +index 05b03f5eab83b..492d69d2fa737 100644 +--- a/fs/btrfs/tests/inode-tests.c ++++ b/fs/btrfs/tests/inode-tests.c +@@ -34,7 +34,11 @@ static void insert_extent(struct btrfs_root *root, u64 start, u64 len, + key.type = BTRFS_EXTENT_DATA_KEY; + key.offset = start; + +- btrfs_setup_item_for_insert(root, &path, &key, value_len); ++ /* ++ * Passing a NULL trans handle is fine here, we have a dummy root eb ++ * and the tree is a single node (level 0). ++ */ ++ btrfs_setup_item_for_insert(NULL, root, &path, &key, value_len); + fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); + btrfs_set_file_extent_generation(leaf, fi, 1); + btrfs_set_file_extent_type(leaf, fi, type); +@@ -64,7 +68,11 @@ static void insert_inode_item_key(struct btrfs_root *root) + key.type = BTRFS_INODE_ITEM_KEY; + key.offset = 0; + +- btrfs_setup_item_for_insert(root, &path, &key, value_len); ++ /* ++ * Passing a NULL trans handle is fine here, we have a dummy root eb ++ * and the tree is a single node (level 0). ++ */ ++ btrfs_setup_item_for_insert(NULL, root, &path, &key, value_len); + } + + /* +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index a00e7a0bc713d..ad0d934991741 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -504,9 +504,9 @@ static int overwrite_item(struct btrfs_trans_handle *trans, + found_size = btrfs_item_size(path->nodes[0], + path->slots[0]); + if (found_size > item_size) +- btrfs_truncate_item(path, item_size, 1); ++ btrfs_truncate_item(trans, path, item_size, 1); + else if (found_size < item_size) +- btrfs_extend_item(path, item_size - found_size); ++ btrfs_extend_item(trans, path, item_size - found_size); + } else if (ret) { + return ret; + } +@@ -574,7 +574,7 @@ static int overwrite_item(struct btrfs_trans_handle *trans, + } + } + no_copy: +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + btrfs_release_path(path); + return 0; + } +@@ -3530,7 +3530,7 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans, + last_offset = max(last_offset, curr_end); + } + btrfs_set_dir_log_end(path->nodes[0], item, last_offset); +- btrfs_mark_buffer_dirty(path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, path->nodes[0]); + btrfs_release_path(path); + return 0; + } +@@ -4488,7 +4488,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, + dst_index++; + } + +- btrfs_mark_buffer_dirty(dst_path->nodes[0]); ++ btrfs_mark_buffer_dirty(trans, dst_path->nodes[0]); + btrfs_release_path(dst_path); + out: + kfree(ins_data); +@@ -4693,7 +4693,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans, + write_extent_buffer(leaf, &fi, + btrfs_item_ptr_offset(leaf, path->slots[0]), + sizeof(fi)); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + btrfs_release_path(path); + +diff --git a/fs/btrfs/uuid-tree.c b/fs/btrfs/uuid-tree.c +index 7c7001f42b14c..5be74f9e47ebf 100644 +--- a/fs/btrfs/uuid-tree.c ++++ b/fs/btrfs/uuid-tree.c +@@ -124,7 +124,7 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, + * An item with that type already exists. + * Extend the item and store the new subid at the end. + */ +- btrfs_extend_item(path, sizeof(subid_le)); ++ btrfs_extend_item(trans, path, sizeof(subid_le)); + eb = path->nodes[0]; + slot = path->slots[0]; + offset = btrfs_item_ptr_offset(eb, slot); +@@ -139,7 +139,7 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, + ret = 0; + subid_le = cpu_to_le64(subid_cpu); + write_extent_buffer(eb, &subid_le, offset, sizeof(subid_le)); +- btrfs_mark_buffer_dirty(eb); ++ btrfs_mark_buffer_dirty(trans, eb); + + out: + btrfs_free_path(path); +@@ -221,7 +221,7 @@ int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, + move_src = offset + sizeof(subid); + move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot)); + memmove_extent_buffer(eb, move_dst, move_src, move_len); +- btrfs_truncate_item(path, item_size - sizeof(subid), 1); ++ btrfs_truncate_item(trans, path, item_size - sizeof(subid), 1); + + out: + btrfs_free_path(path); +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 5019e9244d2d2..1df496c809376 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -1908,7 +1908,7 @@ static int btrfs_add_dev_item(struct btrfs_trans_handle *trans, + ptr = btrfs_device_fsid(dev_item); + write_extent_buffer(leaf, trans->fs_info->fs_devices->metadata_uuid, + ptr, BTRFS_FSID_SIZE); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + ret = 0; + out: +@@ -2613,7 +2613,7 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans) + if (device->fs_devices->seeding) { + btrfs_set_device_generation(leaf, dev_item, + device->generation); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } + + path->slots[0]++; +@@ -2911,7 +2911,7 @@ static noinline int btrfs_update_device(struct btrfs_trans_handle *trans, + btrfs_device_get_disk_total_bytes(device)); + btrfs_set_device_bytes_used(leaf, dev_item, + btrfs_device_get_bytes_used(device)); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + + out: + btrfs_free_path(path); +@@ -3499,7 +3499,7 @@ static int insert_balance_item(struct btrfs_fs_info *fs_info, + + btrfs_set_balance_flags(leaf, item, bctl->flags); + +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + out: + btrfs_free_path(path); + err = btrfs_commit_transaction(trans); +@@ -7513,7 +7513,7 @@ static int update_dev_stat_item(struct btrfs_trans_handle *trans, + for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++) + btrfs_set_dev_stats_value(eb, ptr, i, + btrfs_dev_stat_read(device, i)); +- btrfs_mark_buffer_dirty(eb); ++ btrfs_mark_buffer_dirty(trans, eb); + + out: + btrfs_free_path(path); +diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c +index fc4b20c2688a0..c454b8ce6babe 100644 +--- a/fs/btrfs/xattr.c ++++ b/fs/btrfs/xattr.c +@@ -188,15 +188,15 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, + if (old_data_len + name_len + sizeof(*di) == item_size) { + /* No other xattrs packed in the same leaf item. */ + if (size > old_data_len) +- btrfs_extend_item(path, size - old_data_len); ++ btrfs_extend_item(trans, path, size - old_data_len); + else if (size < old_data_len) +- btrfs_truncate_item(path, data_size, 1); ++ btrfs_truncate_item(trans, path, data_size, 1); + } else { + /* There are other xattrs packed in the same item. */ + ret = btrfs_delete_one_dir_name(trans, root, path, di); + if (ret) + goto out; +- btrfs_extend_item(path, data_size); ++ btrfs_extend_item(trans, path, data_size); + } + + ptr = btrfs_item_ptr(leaf, slot, char); +@@ -205,7 +205,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, + btrfs_set_dir_data_len(leaf, di, size); + data_ptr = ((unsigned long)(di + 1)) + name_len; + write_extent_buffer(leaf, value, data_ptr, size); +- btrfs_mark_buffer_dirty(leaf); ++ btrfs_mark_buffer_dirty(trans, leaf); + } else { + /* + * Insert, and we had space for the xattr, so path->slots[0] is +-- +2.42.0 + diff --git a/queue-6.5/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch b/queue-6.5/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch new file mode 100644 index 00000000000..7bf89c3b07e --- /dev/null +++ b/queue-6.5/cifs-fix-check-of-rc-in-function-generate_smb3signin.patch @@ -0,0 +1,52 @@ +From 96c80897cad71777bc94e9142a2d0a91662ebb9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 19:42:41 +0300 +Subject: cifs: fix check of rc in function generate_smb3signingkey + +From: Ekaterina Esina + +[ Upstream commit 181724fc72486dec2bec8803459be05b5162aaa8 ] + +Remove extra check after condition, add check after generating key +for encryption. The check is needed to return non zero rc before +rewriting it with generating key for decryption. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Reviewed-by: Paulo Alcantara (SUSE) +Fixes: d70e9fa55884 ("cifs: try opening channels after mounting") +Signed-off-by: Ekaterina Esina +Co-developed-by: Anastasia Belova +Signed-off-by: Anastasia Belova +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/smb2transport.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c +index 7676091b3e77a..21fc6d84e396d 100644 +--- a/fs/smb/client/smb2transport.c ++++ b/fs/smb/client/smb2transport.c +@@ -452,6 +452,8 @@ generate_smb3signingkey(struct cifs_ses *ses, + ptriplet->encryption.context, + ses->smb3encryptionkey, + SMB3_ENC_DEC_KEY_SIZE); ++ if (rc) ++ return rc; + rc = generate_key(ses, ptriplet->decryption.label, + ptriplet->decryption.context, + ses->smb3decryptionkey, +@@ -460,9 +462,6 @@ generate_smb3signingkey(struct cifs_ses *ses, + return rc; + } + +- if (rc) +- return rc; +- + #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS + cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__); + /* +-- +2.42.0 + diff --git a/queue-6.5/cifs-spnego-add-in-host_key_len.patch b/queue-6.5/cifs-spnego-add-in-host_key_len.patch new file mode 100644 index 00000000000..2b894ebba0d --- /dev/null +++ b/queue-6.5/cifs-spnego-add-in-host_key_len.patch @@ -0,0 +1,43 @@ +From 702484102f7c0db0cd9474a734168c366b0e306c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 17:52:32 +0300 +Subject: cifs: spnego: add ';' in HOST_KEY_LEN + +From: Anastasia Belova + +[ Upstream commit ff31ba19d732efb9aca3633935d71085e68d5076 ] + +"host=" should start with ';' (as in cifs_get_spnego_key) +So its length should be 6. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Reviewed-by: Paulo Alcantara (SUSE) +Fixes: 7c9c3760b3a5 ("[CIFS] add constants for string lengths of keynames in SPNEGO upcall string") +Signed-off-by: Anastasia Belova +Co-developed-by: Ekaterina Esina +Signed-off-by: Ekaterina Esina +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifs_spnego.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/smb/client/cifs_spnego.c b/fs/smb/client/cifs_spnego.c +index 6f3285f1dfee5..af7849e5974ff 100644 +--- a/fs/smb/client/cifs_spnego.c ++++ b/fs/smb/client/cifs_spnego.c +@@ -64,8 +64,8 @@ struct key_type cifs_spnego_key_type = { + * strlen(";sec=ntlmsspi") */ + #define MAX_MECH_STR_LEN 13 + +-/* strlen of "host=" */ +-#define HOST_KEY_LEN 5 ++/* strlen of ";host=" */ ++#define HOST_KEY_LEN 6 + + /* strlen of ";ip4=" or ";ip6=" */ + #define IP_KEY_LEN 5 +-- +2.42.0 + diff --git a/queue-6.5/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch b/queue-6.5/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch new file mode 100644 index 00000000000..ac8953d5c10 --- /dev/null +++ b/queue-6.5/clocksource-drivers-timer-atmel-tcb-fix-initializati.patch @@ -0,0 +1,56 @@ +From e3479ebd9179c29b6cabe1c265a409264d5b99b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 18:17:13 +0200 +Subject: clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 + hardware + +From: Ronald Wahl + +[ Upstream commit 6d3bc4c02d59996d1d3180d8ed409a9d7d5900e0 ] + +On SAM9 hardware two cascaded 16 bit timers are used to form a 32 bit +high resolution timer that is used as scheduler clock when the kernel +has been configured that way (CONFIG_ATMEL_CLOCKSOURCE_TCB). + +The driver initially triggers a reset-to-zero of the two timers but this +reset is only performed on the next rising clock. For the first timer +this is ok - it will be in the next 60ns (16MHz clock). For the chained +second timer this will only happen after the first timer overflows, i.e. +after 2^16 clocks (~4ms with a 16MHz clock). So with other words the +scheduler clock resets to 0 after the first 2^16 clock cycles. + +It looks like that the scheduler does not like this and behaves wrongly +over its lifetime, e.g. some tasks are scheduled with a long delay. Why +that is and if there are additional requirements for this behaviour has +not been further analysed. + +There is a simple fix for resetting the second timer as well when the +first timer is reset and this is to set the ATMEL_TC_ASWTRG_SET bit in +the Channel Mode register (CMR) of the first timer. This will also rise +the TIOA line (clock input of the second timer) when a software trigger +respective SYNC is issued. + +Signed-off-by: Ronald Wahl +Acked-by: Alexandre Belloni +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20231007161803.31342-1-rwahl@gmx.de +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-atmel-tcb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c +index 27af17c995900..2a90c92a9182a 100644 +--- a/drivers/clocksource/timer-atmel-tcb.c ++++ b/drivers/clocksource/timer-atmel-tcb.c +@@ -315,6 +315,7 @@ static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx) + writel(mck_divisor_idx /* likely divide-by-8 */ + | ATMEL_TC_WAVE + | ATMEL_TC_WAVESEL_UP /* free-run */ ++ | ATMEL_TC_ASWTRG_SET /* TIOA0 rises at software trigger */ + | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ + | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ + tcaddr + ATMEL_TC_REG(0, CMR)); +-- +2.42.0 + diff --git a/queue-6.5/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch b/queue-6.5/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch new file mode 100644 index 00000000000..75d5420ccd9 --- /dev/null +++ b/queue-6.5/clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch @@ -0,0 +1,66 @@ +From b642060095a7f4740f2e6f46ff55a6c69ea8e5bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 16:39:22 +0800 +Subject: clocksource/drivers/timer-imx-gpt: Fix potential memory leak + +From: Jacky Bai + +[ Upstream commit 8051a993ce222a5158bccc6ac22ace9253dd71cb ] + +Fix coverity Issue CID 250382: Resource leak (RESOURCE_LEAK). +Add kfree when error return. + +Signed-off-by: Jacky Bai +Reviewed-by: Peng Fan +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20231009083922.1942971-1-ping.bai@nxp.com +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-imx-gpt.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c +index 28ab4f1a7c713..6a878d227a13b 100644 +--- a/drivers/clocksource/timer-imx-gpt.c ++++ b/drivers/clocksource/timer-imx-gpt.c +@@ -434,12 +434,16 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t + return -ENOMEM; + + imxtm->base = of_iomap(np, 0); +- if (!imxtm->base) +- return -ENXIO; ++ if (!imxtm->base) { ++ ret = -ENXIO; ++ goto err_kfree; ++ } + + imxtm->irq = irq_of_parse_and_map(np, 0); +- if (imxtm->irq <= 0) +- return -EINVAL; ++ if (imxtm->irq <= 0) { ++ ret = -EINVAL; ++ goto err_kfree; ++ } + + imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); + +@@ -452,11 +456,15 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t + + ret = _mxc_timer_init(imxtm); + if (ret) +- return ret; ++ goto err_kfree; + + initialized = 1; + + return 0; ++ ++err_kfree: ++ kfree(imxtm); ++ return ret; + } + + static int __init imx1_timer_init_dt(struct device_node *np) +-- +2.42.0 + diff --git a/queue-6.5/cpu-hotplug-don-t-offline-the-last-non-isolated-cpu.patch b/queue-6.5/cpu-hotplug-don-t-offline-the-last-non-isolated-cpu.patch new file mode 100644 index 00000000000..029d6694e95 --- /dev/null +++ b/queue-6.5/cpu-hotplug-don-t-offline-the-last-non-isolated-cpu.patch @@ -0,0 +1,75 @@ +From ea2a91d78605174d5fe8abf91abe2bedcfe217ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 17:09:53 +0800 +Subject: cpu/hotplug: Don't offline the last non-isolated CPU + +From: Ran Xiaokai + +[ Upstream commit 38685e2a0476127db766f81b1c06019ddc4c9ffa ] + +If a system has isolated CPUs via the "isolcpus=" command line parameter, +then an attempt to offline the last housekeeping CPU will result in a +WARN_ON() when rebuilding the scheduler domains and a subsequent panic due +to and unhandled empty CPU mas in partition_sched_domains_locked(). + +cpuset_hotplug_workfn() + rebuild_sched_domains_locked() + ndoms = generate_sched_domains(&doms, &attr); + cpumask_and(doms[0], top_cpuset.effective_cpus, housekeeping_cpumask(HK_FLAG_DOMAIN)); + +Thus results in an empty CPU mask which triggers the warning and then the +subsequent crash: + +WARNING: CPU: 4 PID: 80 at kernel/sched/topology.c:2366 build_sched_domains+0x120c/0x1408 +Call trace: + build_sched_domains+0x120c/0x1408 + partition_sched_domains_locked+0x234/0x880 + rebuild_sched_domains_locked+0x37c/0x798 + rebuild_sched_domains+0x30/0x58 + cpuset_hotplug_workfn+0x2a8/0x930 + +Unable to handle kernel paging request at virtual address fffe80027ab37080 + partition_sched_domains_locked+0x318/0x880 + rebuild_sched_domains_locked+0x37c/0x798 + +Aside of the resulting crash, it does not make any sense to offline the last +last housekeeping CPU. + +Prevent this by masking out the non-housekeeping CPUs when selecting a +target CPU for initiating the CPU unplug operation via the work queue. + +Suggested-by: Thomas Gleixner +Signed-off-by: Ran Xiaokai +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/202310171709530660462@zte.com.cn +Signed-off-by: Sasha Levin +--- + kernel/cpu.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 26119d2154102..189ba5fd9af4b 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1503,11 +1503,14 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) + /* + * Ensure that the control task does not run on the to be offlined + * CPU to prevent a deadlock against cfs_b->period_timer. ++ * Also keep at least one housekeeping cpu onlined to avoid generating ++ * an empty sched_domain span. + */ +- cpu = cpumask_any_but(cpu_online_mask, cpu); +- if (cpu >= nr_cpu_ids) +- return -EBUSY; +- return work_on_cpu(cpu, __cpu_down_maps_locked, &work); ++ for_each_cpu_and(cpu, cpu_online_mask, housekeeping_cpumask(HK_TYPE_DOMAIN)) { ++ if (cpu != work.cpu) ++ return work_on_cpu(cpu, __cpu_down_maps_locked, &work); ++ } ++ return -EBUSY; + } + + static int cpu_down(unsigned int cpu, enum cpuhp_state target) +-- +2.42.0 + diff --git a/queue-6.5/crypto-hisilicon-qm-prevent-soft-lockup-in-receive-l.patch b/queue-6.5/crypto-hisilicon-qm-prevent-soft-lockup-in-receive-l.patch new file mode 100644 index 00000000000..82d4c09eba7 --- /dev/null +++ b/queue-6.5/crypto-hisilicon-qm-prevent-soft-lockup-in-receive-l.patch @@ -0,0 +1,60 @@ +From 461aa57735afc2310f918ced61e2350ea1af079c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 17:35:58 +0800 +Subject: crypto: hisilicon/qm - prevent soft lockup in receive loop + +From: Longfang Liu + +[ Upstream commit 33fc506d2ac514be1072499a263c3bff8c7c95a0 ] + +In the scenario where the accelerator business is fully loaded. +When the workqueue receiving messages and performing callback +processing, there are a large number of messages that need to be +received, and there are continuously messages that have been +processed and need to be received. +This will cause the receive loop here to be locked for a long time. +This scenario will cause watchdog timeout problems on OS with kernel +preemption turned off. + +The error logs: +watchdog: BUG: soft lockup - CPU#23 stuck for 23s! [kworker/u262:1:1407] +[ 1461.978428][ C23] Call trace: +[ 1461.981890][ C23] complete+0x8c/0xf0 +[ 1461.986031][ C23] kcryptd_async_done+0x154/0x1f4 [dm_crypt] +[ 1461.992154][ C23] sec_skcipher_callback+0x7c/0xf4 [hisi_sec2] +[ 1461.998446][ C23] sec_req_cb+0x104/0x1f4 [hisi_sec2] +[ 1462.003950][ C23] qm_poll_req_cb+0xcc/0x150 [hisi_qm] +[ 1462.009531][ C23] qm_work_process+0x60/0xc0 [hisi_qm] +[ 1462.015101][ C23] process_one_work+0x1c4/0x470 +[ 1462.020052][ C23] worker_thread+0x150/0x3c4 +[ 1462.024735][ C23] kthread+0x108/0x13c +[ 1462.028889][ C23] ret_from_fork+0x10/0x18 + +Therefore, it is necessary to add an actively scheduled operation in the +while loop to prevent this problem. +After adding it, no matter whether the OS turns on or off the kernel +preemption function. Neither will cause watchdog timeout issues. + +Signed-off-by: Longfang Liu +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index ba4852744c052..2aec118ba6775 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -845,6 +845,8 @@ static void qm_poll_req_cb(struct hisi_qp *qp) + qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, + qp->qp_status.cq_head, 0); + atomic_dec(&qp->qp_status.used); ++ ++ cond_resched(); + } + + /* set c_flag */ +-- +2.42.0 + diff --git a/queue-6.5/crypto-pcrypt-fix-hungtask-for-padata_reset.patch b/queue-6.5/crypto-pcrypt-fix-hungtask-for-padata_reset.patch new file mode 100644 index 00000000000..366fc98b024 --- /dev/null +++ b/queue-6.5/crypto-pcrypt-fix-hungtask-for-padata_reset.patch @@ -0,0 +1,106 @@ +From 7f6355e715d36155c80a1eeac1fbecb3c8802df3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 13:33:41 +0000 +Subject: crypto: pcrypt - Fix hungtask for PADATA_RESET + +From: Lu Jialin + +[ Upstream commit 8f4f68e788c3a7a696546291258bfa5fdb215523 ] + +We found a hungtask bug in test_aead_vec_cfg as follows: + +INFO: task cryptomgr_test:391009 blocked for more than 120 seconds. +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +Call trace: + __switch_to+0x98/0xe0 + __schedule+0x6c4/0xf40 + schedule+0xd8/0x1b4 + schedule_timeout+0x474/0x560 + wait_for_common+0x368/0x4e0 + wait_for_completion+0x20/0x30 + wait_for_completion+0x20/0x30 + test_aead_vec_cfg+0xab4/0xd50 + test_aead+0x144/0x1f0 + alg_test_aead+0xd8/0x1e0 + alg_test+0x634/0x890 + cryptomgr_test+0x40/0x70 + kthread+0x1e0/0x220 + ret_from_fork+0x10/0x18 + Kernel panic - not syncing: hung_task: blocked tasks + +For padata_do_parallel, when the return err is 0 or -EBUSY, it will call +wait_for_completion(&wait->completion) in test_aead_vec_cfg. In normal +case, aead_request_complete() will be called in pcrypt_aead_serial and the +return err is 0 for padata_do_parallel. But, when pinst->flags is +PADATA_RESET, the return err is -EBUSY for padata_do_parallel, and it +won't call aead_request_complete(). Therefore, test_aead_vec_cfg will +hung at wait_for_completion(&wait->completion), which will cause +hungtask. + +The problem comes as following: +(padata_do_parallel) | + rcu_read_lock_bh(); | + err = -EINVAL; | (padata_replace) + | pinst->flags |= PADATA_RESET; + err = -EBUSY | + if (pinst->flags & PADATA_RESET) | + rcu_read_unlock_bh() | + return err + +In order to resolve the problem, we replace the return err -EBUSY with +-EAGAIN, which means parallel_data is changing, and the caller should call +it again. + +v3: +remove retry and just change the return err. +v2: +introduce padata_try_do_parallel() in pcrypt_aead_encrypt and +pcrypt_aead_decrypt to solve the hungtask. + +Signed-off-by: Lu Jialin +Signed-off-by: Guo Zihua +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/pcrypt.c | 4 ++++ + kernel/padata.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c +index 8c1d0ca412137..d0d954fe9d54f 100644 +--- a/crypto/pcrypt.c ++++ b/crypto/pcrypt.c +@@ -117,6 +117,8 @@ static int pcrypt_aead_encrypt(struct aead_request *req) + err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu); + if (!err) + return -EINPROGRESS; ++ if (err == -EBUSY) ++ return -EAGAIN; + + return err; + } +@@ -164,6 +166,8 @@ static int pcrypt_aead_decrypt(struct aead_request *req) + err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu); + if (!err) + return -EINPROGRESS; ++ if (err == -EBUSY) ++ return -EAGAIN; + + return err; + } +diff --git a/kernel/padata.c b/kernel/padata.c +index ff349e1084c1d..179fb1518070c 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -202,7 +202,7 @@ int padata_do_parallel(struct padata_shell *ps, + *cb_cpu = cpu; + } + +- err = -EBUSY; ++ err = -EBUSY; + if ((pinst->flags & PADATA_RESET)) + goto out; + +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-check-num-of-link-levels-when-update-pcie-pa.patch b/queue-6.5/drm-amd-check-num-of-link-levels-when-update-pcie-pa.patch new file mode 100644 index 00000000000..f9307e90848 --- /dev/null +++ b/queue-6.5/drm-amd-check-num-of-link-levels-when-update-pcie-pa.patch @@ -0,0 +1,37 @@ +From 21727211ca951c8df3bc2bf63b0c6fd6b0208ac2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 11:32:41 +0800 +Subject: drm/amd: check num of link levels when update pcie param + +From: Lin.Cao + +[ Upstream commit 406e8845356d18bdf3d3a23b347faf67706472ec ] + +In SR-IOV environment, the value of pcie_table->num_of_link_levels will +be 0, and num_of_levels - 1 will cause array index out of bounds + +Signed-off-by: Lin.Cao +Acked-by: Jingwen Chen +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +index 223e890575a2b..3bc60ecc7bfef 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +@@ -2436,6 +2436,9 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu, + uint32_t smu_pcie_arg; + int ret, i; + ++ if (!num_of_levels) ++ return 0; ++ + if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { + if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap) + pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1]; +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-disable-pp_pcie_dpm_mask-when-dynamic-speed-.patch b/queue-6.5/drm-amd-disable-pp_pcie_dpm_mask-when-dynamic-speed-.patch new file mode 100644 index 00000000000..339f73555ac --- /dev/null +++ b/queue-6.5/drm-amd-disable-pp_pcie_dpm_mask-when-dynamic-speed-.patch @@ -0,0 +1,81 @@ +From 6ef68dfb6fcb1f957903aa81dabc9f2c83f03ac4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 15:42:00 -0500 +Subject: drm/amd: Disable PP_PCIE_DPM_MASK when dynamic speed switching not + supported + +From: Mario Limonciello + +[ Upstream commit fbf1035b033a51eee48d5f42e781b02fff272ca0 ] + +Rather than individual ASICs checking for the quirk, set the quirk at the +driver level. + +Signed-off-by: Mario Limonciello +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ + drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 4 +--- + drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 2 +- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 +- + 4 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index ecc61a6d13e13..65779cbdbad13 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -2318,6 +2318,8 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) + adev->pm.pp_feature &= ~PP_GFXOFF_MASK; + if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID) + adev->pm.pp_feature &= ~PP_OVERDRIVE_MASK; ++ if (!amdgpu_device_pcie_dynamic_switching_supported()) ++ adev->pm.pp_feature &= ~PP_PCIE_DPM_MASK; + + total = true; + for (i = 0; i < adev->num_ip_blocks; i++) { +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index 1cb4022644977..a38888176805d 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -1823,9 +1823,7 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) + + data->mclk_dpm_key_disabled = hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true; + data->sclk_dpm_key_disabled = hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true; +- data->pcie_dpm_key_disabled = +- !amdgpu_device_pcie_dynamic_switching_supported() || +- !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); ++ data->pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); + /* need to set voltage control types before EVV patching */ + data->voltage_control = SMU7_VOLTAGE_CONTROL_NONE; + data->vddci_control = SMU7_VOLTAGE_CONTROL_NONE; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +index 9a5f3d31e7780..94f22df5ac205 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +@@ -2107,7 +2107,7 @@ static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, + min_lane_width = min_lane_width > max_lane_width ? + max_lane_width : min_lane_width; + +- if (!amdgpu_device_pcie_dynamic_switching_supported()) { ++ if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { + pcie_table->pcie_gen[0] = max_gen_speed; + pcie_table->pcie_lane[0] = max_lane_width; + } else { +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +index 4fa94f583b87c..223e890575a2b 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +@@ -2436,7 +2436,7 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu, + uint32_t smu_pcie_arg; + int ret, i; + +- if (!amdgpu_device_pcie_dynamic_switching_supported()) { ++ if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { + if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap) + pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1]; + +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-display-add-seamless-pipe-topology-transitio.patch b/queue-6.5/drm-amd-display-add-seamless-pipe-topology-transitio.patch new file mode 100644 index 00000000000..160a7f64f06 --- /dev/null +++ b/queue-6.5/drm-amd-display-add-seamless-pipe-topology-transitio.patch @@ -0,0 +1,151 @@ +From 6106e3055a0c6ff7f883ca1cf269eb35500fa3aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 17:08:48 -0400 +Subject: drm/amd/display: add seamless pipe topology transition check + +From: Wenjing Liu + +[ Upstream commit 15c6798ae26d5c7a7776f4f7d0c1fa8c462688a2 ] + +[why] +We have a few cases where we need to perform update topology update +in dc update interface. However some of the updates are not seamless +This could cause user noticible glitches. To enforce seamless transition +we are adding a checking condition and error logging so the corruption +as result of non seamless transition can be easily spotted. + +Reviewed-by: Dillon Varone +Acked-by: Stylon Wang +Signed-off-by: Wenjing Liu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 8 +++ + .../drm/amd/display/dc/dcn32/dcn32_hwseq.c | 52 +++++++++++++++++++ + .../drm/amd/display/dc/dcn32/dcn32_hwseq.h | 4 ++ + .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c | 1 + + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 ++ + 5 files changed, 68 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index ab79bcd264164..93e6265e58509 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -4414,6 +4414,14 @@ bool dc_update_planes_and_stream(struct dc *dc, + update_type, + context); + } else { ++ if (!stream_update && ++ dc->hwss.is_pipe_topology_transition_seamless && ++ !dc->hwss.is_pipe_topology_transition_seamless( ++ dc, dc->current_state, context)) { ++ ++ DC_LOG_ERROR("performing non-seamless pipe topology transition with surface only update!\n"); ++ BREAK_TO_DEBUGGER(); ++ } + commit_planes_for_stream( + dc, + srf_updates, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +index b6608d7ab4450..5b3d0e5b90a3e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +@@ -1621,3 +1621,55 @@ void dcn32_blank_phantom(struct dc *dc, + if (tg->funcs->is_tg_enabled(tg)) + hws->funcs.wait_for_blank_complete(opp); + } ++ ++bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc, ++ const struct dc_state *cur_ctx, ++ const struct dc_state *new_ctx) ++{ ++ int i; ++ const struct pipe_ctx *cur_pipe, *new_pipe; ++ bool is_seamless = true; ++ ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ cur_pipe = &cur_ctx->res_ctx.pipe_ctx[i]; ++ new_pipe = &new_ctx->res_ctx.pipe_ctx[i]; ++ ++ if (resource_is_pipe_type(cur_pipe, FREE_PIPE) || ++ resource_is_pipe_type(new_pipe, FREE_PIPE)) ++ /* adding or removing free pipes is always seamless */ ++ continue; ++ else if (resource_is_pipe_type(cur_pipe, OTG_MASTER)) { ++ if (resource_is_pipe_type(new_pipe, OTG_MASTER)) ++ if (cur_pipe->stream->stream_id == new_pipe->stream->stream_id) ++ /* OTG master with the same stream is seamless */ ++ continue; ++ } else if (resource_is_pipe_type(cur_pipe, OPP_HEAD)) { ++ if (resource_is_pipe_type(new_pipe, OPP_HEAD)) { ++ if (cur_pipe->stream_res.tg == new_pipe->stream_res.tg) ++ /* ++ * OPP heads sharing the same timing ++ * generator is seamless ++ */ ++ continue; ++ } ++ } else if (resource_is_pipe_type(cur_pipe, DPP_PIPE)) { ++ if (resource_is_pipe_type(new_pipe, DPP_PIPE)) { ++ if (cur_pipe->stream_res.opp == new_pipe->stream_res.opp) ++ /* ++ * DPP pipes sharing the same OPP head is ++ * seamless ++ */ ++ continue; ++ } ++ } ++ ++ /* ++ * This pipe's transition doesn't fall under any seamless ++ * conditions ++ */ ++ is_seamless = false; ++ break; ++ } ++ ++ return is_seamless; ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +index 616d5219119e9..9992e40acd217 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +@@ -120,4 +120,8 @@ void dcn32_blank_phantom(struct dc *dc, + int width, + int height); + ++bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc, ++ const struct dc_state *cur_ctx, ++ const struct dc_state *new_ctx); ++ + #endif /* __DC_HWSS_DCN32_H__ */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +index 279f312f74076..12e0f48a13e48 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +@@ -116,6 +116,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { + .update_dsc_pg = dcn32_update_dsc_pg, + .apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom, + .blank_phantom = dcn32_blank_phantom, ++ .is_pipe_topology_transition_seamless = dcn32_is_pipe_topology_transition_seamless, + }; + + static const struct hwseq_private_funcs dcn32_private_funcs = { +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 7a702e216e530..66e680902c95c 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -401,6 +401,9 @@ struct hw_sequencer_funcs { + struct dc_state *context, + struct pipe_ctx *phantom_pipe); + void (*apply_update_flags_for_phantom)(struct pipe_ctx *phantom_pipe); ++ bool (*is_pipe_topology_transition_seamless)(struct dc *dc, ++ const struct dc_state *cur_ctx, ++ const struct dc_state *new_ctx); + + void (*commit_subvp_config)(struct dc *dc, struct dc_state *context); + void (*enable_phantom_streams)(struct dc *dc, struct dc_state *context); +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-display-avoid-null-dereference-of-timing-gen.patch b/queue-6.5/drm-amd-display-avoid-null-dereference-of-timing-gen.patch new file mode 100644 index 00000000000..9c5dd82f19b --- /dev/null +++ b/queue-6.5/drm-amd-display-avoid-null-dereference-of-timing-gen.patch @@ -0,0 +1,48 @@ +From fd9b4acc5216307822b2649f9d3fa31c108377bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 10:14:49 +0800 +Subject: drm/amd/display: Avoid NULL dereference of timing generator + +From: Wayne Lin + +[ Upstream commit b1904ed480cee3f9f4036ea0e36d139cb5fee2d6 ] + +[Why & How] +Check whether assigned timing generator is NULL or not before +accessing its funcs to prevent NULL dereference. + +Reviewed-by: Jun Lei +Acked-by: Hersen Wu +Signed-off-by: Wayne Lin +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +index 6e11d2b701f82..569d40eb7059d 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -556,7 +556,7 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream) + for (i = 0; i < MAX_PIPES; i++) { + struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; + +- if (res_ctx->pipe_ctx[i].stream != stream) ++ if (res_ctx->pipe_ctx[i].stream != stream || !tg) + continue; + + return tg->funcs->get_frame_count(tg); +@@ -615,7 +615,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, + for (i = 0; i < MAX_PIPES; i++) { + struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; + +- if (res_ctx->pipe_ctx[i].stream != stream) ++ if (res_ctx->pipe_ctx[i].stream != stream || !tg) + continue; + + tg->funcs->get_scanoutpos(tg, +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-display-blank-phantom-otg-before-enabling.patch b/queue-6.5/drm-amd-display-blank-phantom-otg-before-enabling.patch new file mode 100644 index 00000000000..3410c1f4bc8 --- /dev/null +++ b/queue-6.5/drm-amd-display-blank-phantom-otg-before-enabling.patch @@ -0,0 +1,217 @@ +From 3327ba4775bd8e8eab5b5257d57313942b36e816 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Aug 2023 13:21:58 -0400 +Subject: drm/amd/display: Blank phantom OTG before enabling + +From: Alvin Lee + +[ Upstream commit e87a6c5b7780b5f423797351eb586ed96cc6d151 ] + +[Description] +Before enabling the phantom OTG for an update we +must enable DPG to avoid underflow. + +Reviewed-by: Samson Tam +Acked-by: Stylon Wang +Signed-off-by: Alvin Lee +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 50 +------------------ + .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 10 +++- + .../drm/amd/display/dc/dcn32/dcn32_hwseq.c | 46 +++++++++++++++++ + .../drm/amd/display/dc/dcn32/dcn32_hwseq.h | 5 ++ + .../gpu/drm/amd/display/dc/dcn32/dcn32_init.c | 1 + + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 5 ++ + 6 files changed, 68 insertions(+), 49 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 609048160aa20..ab79bcd264164 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1070,53 +1070,6 @@ static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *contex + } + } + +-static void phantom_pipe_blank( +- struct dc *dc, +- struct timing_generator *tg, +- int width, +- int height) +-{ +- struct dce_hwseq *hws = dc->hwseq; +- enum dc_color_space color_space; +- struct tg_color black_color = {0}; +- struct output_pixel_processor *opp = NULL; +- uint32_t num_opps, opp_id_src0, opp_id_src1; +- uint32_t otg_active_width, otg_active_height; +- uint32_t i; +- +- /* program opp dpg blank color */ +- color_space = COLOR_SPACE_SRGB; +- color_space_to_black_color(dc, color_space, &black_color); +- +- otg_active_width = width; +- otg_active_height = height; +- +- /* get the OPTC source */ +- tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); +- ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp); +- +- for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) { +- if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) { +- opp = dc->res_pool->opps[i]; +- break; +- } +- } +- +- if (opp && opp->funcs->opp_set_disp_pattern_generator) +- opp->funcs->opp_set_disp_pattern_generator( +- opp, +- CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, +- CONTROLLER_DP_COLOR_SPACE_UDEFINED, +- COLOR_DEPTH_UNDEFINED, +- &black_color, +- otg_active_width, +- otg_active_height, +- 0); +- +- if (tg->funcs->is_tg_enabled(tg)) +- hws->funcs.wait_for_blank_complete(opp); +-} +- + static void dc_update_viusal_confirm_color(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx) + { + if (dc->ctx->dce_version >= DCN_VERSION_1_0) { +@@ -1207,7 +1160,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) + + main_pipe_width = old_stream->mall_stream_config.paired_stream->dst.width; + main_pipe_height = old_stream->mall_stream_config.paired_stream->dst.height; +- phantom_pipe_blank(dc, tg, main_pipe_width, main_pipe_height); ++ if (dc->hwss.blank_phantom) ++ dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height); + tg->funcs->enable_crtc(tg); + } + } +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 62a077adcdbfa..84fe449a2c7ed 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1846,8 +1846,16 @@ void dcn20_program_front_end_for_ctx( + dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) { + struct timing_generator *tg = dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg; + +- if (tg->funcs->enable_crtc) ++ if (tg->funcs->enable_crtc) { ++ if (dc->hwss.blank_phantom) { ++ int main_pipe_width, main_pipe_height; ++ ++ main_pipe_width = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.width; ++ main_pipe_height = dc->current_state->res_ctx.pipe_ctx[i].stream->mall_stream_config.paired_stream->dst.height; ++ dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height); ++ } + tg->funcs->enable_crtc(tg); ++ } + } + } + /* OTG blank before disabling all front ends */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +index d52d5feeb311b..b6608d7ab4450 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +@@ -1575,3 +1575,49 @@ void dcn32_init_blank( + if (opp) + hws->funcs.wait_for_blank_complete(opp); + } ++ ++void dcn32_blank_phantom(struct dc *dc, ++ struct timing_generator *tg, ++ int width, ++ int height) ++{ ++ struct dce_hwseq *hws = dc->hwseq; ++ enum dc_color_space color_space; ++ struct tg_color black_color = {0}; ++ struct output_pixel_processor *opp = NULL; ++ uint32_t num_opps, opp_id_src0, opp_id_src1; ++ uint32_t otg_active_width, otg_active_height; ++ uint32_t i; ++ ++ /* program opp dpg blank color */ ++ color_space = COLOR_SPACE_SRGB; ++ color_space_to_black_color(dc, color_space, &black_color); ++ ++ otg_active_width = width; ++ otg_active_height = height; ++ ++ /* get the OPTC source */ ++ tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); ++ ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp); ++ ++ for (i = 0; i < dc->res_pool->res_cap->num_opp; i++) { ++ if (dc->res_pool->opps[i] != NULL && dc->res_pool->opps[i]->inst == opp_id_src0) { ++ opp = dc->res_pool->opps[i]; ++ break; ++ } ++ } ++ ++ if (opp && opp->funcs->opp_set_disp_pattern_generator) ++ opp->funcs->opp_set_disp_pattern_generator( ++ opp, ++ CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR, ++ CONTROLLER_DP_COLOR_SPACE_UDEFINED, ++ COLOR_DEPTH_UNDEFINED, ++ &black_color, ++ otg_active_width, ++ otg_active_height, ++ 0); ++ ++ if (tg->funcs->is_tg_enabled(tg)) ++ hws->funcs.wait_for_blank_complete(opp); ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +index 2d2628f31bed7..616d5219119e9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h +@@ -115,4 +115,9 @@ void dcn32_init_blank( + struct dc *dc, + struct timing_generator *tg); + ++void dcn32_blank_phantom(struct dc *dc, ++ struct timing_generator *tg, ++ int width, ++ int height); ++ + #endif /* __DC_HWSS_DCN32_H__ */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +index 777b2fac20c4e..279f312f74076 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c +@@ -115,6 +115,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { + .update_phantom_vp_position = dcn32_update_phantom_vp_position, + .update_dsc_pg = dcn32_update_dsc_pg, + .apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom, ++ .blank_phantom = dcn32_blank_phantom, + }; + + static const struct hwseq_private_funcs dcn32_private_funcs = { +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 02ff99f7bec2b..7a702e216e530 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -388,6 +388,11 @@ struct hw_sequencer_funcs { + void (*z10_restore)(const struct dc *dc); + void (*z10_save_init)(struct dc *dc); + ++ void (*blank_phantom)(struct dc *dc, ++ struct timing_generator *tg, ++ int width, ++ int height); ++ + void (*update_visual_confirm_color)(struct dc *dc, + struct pipe_ctx *pipe_ctx, + int mpcc_id); +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-display-don-t-lock-phantom-pipe-on-disabling.patch b/queue-6.5/drm-amd-display-don-t-lock-phantom-pipe-on-disabling.patch new file mode 100644 index 00000000000..0e912c8e76f --- /dev/null +++ b/queue-6.5/drm-amd-display-don-t-lock-phantom-pipe-on-disabling.patch @@ -0,0 +1,43 @@ +From 207e281ef3bd6699cabe91338a3a437b91f15256 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Aug 2023 10:18:36 -0400 +Subject: drm/amd/display: Don't lock phantom pipe on disabling + +From: Alvin Lee + +[ Upstream commit cbb4c9bc55427774ca4d819933e1b5fa38a6fb44 ] + +[Description] +- When disabling a phantom pipe, we first enable the phantom + OTG so the double buffer update can successfully take place +- However, want to avoid locking the phantom otherwise setting + DPG_EN=1 for the phantom pipe is blocked (without this we could + hit underflow due to phantom HUBP being blanked by default) + +Reviewed-by: Samson Tam +Acked-by: Stylon Wang +Signed-off-by: Alvin Lee +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 9834b75f1837b..79befa17bb037 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -111,7 +111,8 @@ void dcn10_lock_all_pipes(struct dc *dc, + if (pipe_ctx->top_pipe || + !pipe_ctx->stream || + (!pipe_ctx->plane_state && !old_pipe_ctx->plane_state) || +- !tg->funcs->is_tg_enabled(tg)) ++ !tg->funcs->is_tg_enabled(tg) || ++ pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM) + continue; + + if (lock) +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-display-fix-num_ways-overflow-error.patch b/queue-6.5/drm-amd-display-fix-num_ways-overflow-error.patch new file mode 100644 index 00000000000..5910b3952b4 --- /dev/null +++ b/queue-6.5/drm-amd-display-fix-num_ways-overflow-error.patch @@ -0,0 +1,64 @@ +From 917096f3bbc7e1f2cf8c6ff5b60a5b9e28fc1e46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 01:31:12 -0400 +Subject: drm/amd/display: fix num_ways overflow error + +From: Samson Tam + +[ Upstream commit 79f3f1b66753b3a3a269d73676bf50987921f267 ] + +[Why] +Helper function calculates num_ways using 32-bit. But is + returned as 8-bit. If num_ways exceeds 8-bit, then it + reports back the incorrect num_ways and erroneously + uses MALL when it should not + +[How] +Make returned value 32-bit and convert after it checks + against caps.cache_num_ways, which is under 8-bit + +Reviewed-by: Alvin Lee +Acked-by: Roman Li +Signed-off-by: Samson Tam +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +index 5b3d0e5b90a3e..ccbcfd6bd6b85 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +@@ -216,7 +216,7 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc) + static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx) + { + int i; +- uint8_t num_ways = 0; ++ uint32_t num_ways = 0; + uint32_t mall_ss_size_bytes = 0; + + mall_ss_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_size_bytes; +@@ -246,7 +246,8 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c + bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable) + { + union dmub_rb_cmd cmd; +- uint8_t ways, i; ++ uint8_t i; ++ uint32_t ways; + int j; + bool mall_ss_unsupported = false; + struct dc_plane_state *plane = NULL; +@@ -306,7 +307,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable) + cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS; + cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB; + cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header); +- cmd.cab.cab_alloc_ways = ways; ++ cmd.cab.cab_alloc_ways = (uint8_t)ways; + + dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT); + +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-display-use-full-update-for-clip-size-increa.patch b/queue-6.5/drm-amd-display-use-full-update-for-clip-size-increa.patch new file mode 100644 index 00000000000..3923a516e18 --- /dev/null +++ b/queue-6.5/drm-amd-display-use-full-update-for-clip-size-increa.patch @@ -0,0 +1,93 @@ +From 0119361bb09d5ac4c618b09898c5aae140536bd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 14:43:21 -0400 +Subject: drm/amd/display: use full update for clip size increase of large + plane source + +From: Wenjing Liu + +[ Upstream commit 05b78277ef0efc1deebc8a22384fffec29a3676e ] + +[why] +Clip size increase will increase viewport, which could cause us to +switch to MPC combine. +If we skip full update, we are not able to change to MPC combine in +fast update. This will cause corruption showing on the video plane. + +[how] +treat clip size increase of a surface larger than 5k as a full update. + +Reviewed-by: Jun Lei +Acked-by: Aurabindo Pillai +Signed-off-by: Wenjing Liu +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 12 ++++++++++-- + drivers/gpu/drm/amd/display/dc/dc.h | 5 +++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 93e6265e58509..b386f3b0fd428 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -993,7 +993,8 @@ static bool dc_construct(struct dc *dc, + /* set i2c speed if not done by the respective dcnxxx__resource.c */ + if (dc->caps.i2c_speed_in_khz_hdcp == 0) + dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz; +- ++ if (dc->caps.max_optimizable_video_width == 0) ++ dc->caps.max_optimizable_video_width = 5120; + dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); + if (!dc->clk_mgr) + goto fail; +@@ -2430,6 +2431,7 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa + } + + static enum surface_update_type get_scaling_info_update_type( ++ const struct dc *dc, + const struct dc_surface_update *u) + { + union surface_update_flags *update_flags = &u->surface->update_flags; +@@ -2464,6 +2466,12 @@ static enum surface_update_type get_scaling_info_update_type( + update_flags->bits.clock_change = 1; + } + ++ if (u->scaling_info->src_rect.width > dc->caps.max_optimizable_video_width && ++ (u->scaling_info->clip_rect.width > u->surface->clip_rect.width || ++ u->scaling_info->clip_rect.height > u->surface->clip_rect.height)) ++ /* Changing clip size of a large surface may result in MPC slice count change */ ++ update_flags->bits.bandwidth_change = 1; ++ + if (u->scaling_info->src_rect.x != u->surface->src_rect.x + || u->scaling_info->src_rect.y != u->surface->src_rect.y + || u->scaling_info->clip_rect.x != u->surface->clip_rect.x +@@ -2501,7 +2509,7 @@ static enum surface_update_type det_surface_update(const struct dc *dc, + type = get_plane_info_update_type(u); + elevate_update_type(&overall_type, type); + +- type = get_scaling_info_update_type(u); ++ type = get_scaling_info_update_type(dc, u); + elevate_update_type(&overall_type, type); + + if (u->flip_addr) { +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index 81258392d44a1..dc0e0af616506 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -229,6 +229,11 @@ struct dc_caps { + uint32_t dmdata_alloc_size; + unsigned int max_cursor_size; + unsigned int max_video_width; ++ /* ++ * max video plane width that can be safely assumed to be always ++ * supported by single DPP pipe. ++ */ ++ unsigned int max_optimizable_video_width; + unsigned int min_horizontal_blanking_period; + int linear_pitch_alignment; + bool dcc_const_color; +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch b/queue-6.5/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch new file mode 100644 index 00000000000..9abd141d904 --- /dev/null +++ b/queue-6.5/drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch @@ -0,0 +1,81 @@ +From 1890d24c4d80aebc4b649e7e72d5b024b845b355 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 15:46:44 -0500 +Subject: drm/amd: Fix UBSAN array-index-out-of-bounds for Polaris and Tonga + +From: Mario Limonciello + +[ Upstream commit 0f0e59075b5c22f1e871fbd508d6e4f495048356 ] + +For pptable structs that use flexible array sizes, use flexible arrays. + +Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2036742 +Signed-off-by: Mario Limonciello +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +index 41444e27bfc0c..e0e40b054c08b 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +@@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State { + typedef struct _ATOM_Tonga_State_Array { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_State entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_State entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_State_Array; + + typedef struct _ATOM_Tonga_MCLK_Dependency_Record { +@@ -210,7 +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Record { + typedef struct _ATOM_Polaris_SCLK_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Polaris_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Polaris_SCLK_Dependency_Table; + + typedef struct _ATOM_Tonga_PCIE_Record { +@@ -222,7 +222,7 @@ typedef struct _ATOM_Tonga_PCIE_Record { + typedef struct _ATOM_Tonga_PCIE_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_PCIE_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_PCIE_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_PCIE_Table; + + typedef struct _ATOM_Polaris10_PCIE_Record { +@@ -235,7 +235,7 @@ typedef struct _ATOM_Polaris10_PCIE_Record { + typedef struct _ATOM_Polaris10_PCIE_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Polaris10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Polaris10_PCIE_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Polaris10_PCIE_Table; + + +@@ -252,7 +252,7 @@ typedef struct _ATOM_Tonga_MM_Dependency_Record { + typedef struct _ATOM_Tonga_MM_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_MM_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_MM_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_MM_Dependency_Table; + + typedef struct _ATOM_Tonga_Voltage_Lookup_Record { +@@ -265,7 +265,7 @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Record { + typedef struct _ATOM_Tonga_Voltage_Lookup_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_Voltage_Lookup_Table; + + typedef struct _ATOM_Tonga_Fan_Table { +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch b/queue-6.5/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch new file mode 100644 index 00000000000..ac7766d619b --- /dev/null +++ b/queue-6.5/drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch @@ -0,0 +1,69 @@ +From fea8ba2f674d8f43adfb009c0a169cec1e9b32c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 15:22:52 -0500 +Subject: drm/amd: Fix UBSAN array-index-out-of-bounds for SMU7 + +From: Mario Limonciello + +[ Upstream commit 760efbca74a405dc439a013a5efaa9fadc95a8c3 ] + +For pptable structs that use flexible array sizes, use flexible arrays. + +Suggested-by: Felix Held +Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2874 +Signed-off-by: Mario Limonciello +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/include/pptable.h | 4 ++-- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/include/pptable.h b/drivers/gpu/drm/amd/include/pptable.h +index 0b6a057e0a4c4..5aac8d545bdc6 100644 +--- a/drivers/gpu/drm/amd/include/pptable.h ++++ b/drivers/gpu/drm/amd/include/pptable.h +@@ -78,7 +78,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER + typedef struct _ATOM_PPLIB_STATE + { + UCHAR ucNonClockStateIndex; +- UCHAR ucClockStateIndices[1]; // variable-sized ++ UCHAR ucClockStateIndices[]; // variable-sized + } ATOM_PPLIB_STATE; + + +@@ -473,7 +473,7 @@ typedef struct _ATOM_PPLIB_STATE_V2 + /** + * Driver will read the first ucNumDPMLevels in this array + */ +- UCHAR clockInfoIndex[1]; ++ UCHAR clockInfoIndex[]; + } ATOM_PPLIB_STATE_V2; + + typedef struct _StateArray{ +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +index b0ac4d121adca..41444e27bfc0c 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +@@ -179,7 +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Record { + typedef struct _ATOM_Tonga_MCLK_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_MCLK_Dependency_Table; + + typedef struct _ATOM_Tonga_SCLK_Dependency_Record { +@@ -194,7 +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Record { + typedef struct _ATOM_Tonga_SCLK_Dependency_Table { + UCHAR ucRevId; + UCHAR ucNumEntries; /* Number of entries. */ +- ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ++ ATOM_Tonga_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ + } ATOM_Tonga_SCLK_Dependency_Table; + + typedef struct _ATOM_Polaris_SCLK_Dependency_Record { +-- +2.42.0 + diff --git a/queue-6.5/drm-amd-update-update_pcie_parameters-functions-to-u.patch b/queue-6.5/drm-amd-update-update_pcie_parameters-functions-to-u.patch new file mode 100644 index 00000000000..40029927e18 --- /dev/null +++ b/queue-6.5/drm-amd-update-update_pcie_parameters-functions-to-u.patch @@ -0,0 +1,127 @@ +From a8468b19ab9d30531885ec06d677d701d90cbd45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 22:12:18 -0500 +Subject: drm/amd: Update `update_pcie_parameters` functions to use uint8_t + arguments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mario Limonciello + +[ Upstream commit 7752ccf85b929a22e658ec145283e8f31232f4bb ] + +The matching values for `pcie_gen_cap` and `pcie_width_cap` when +fetched from powerplay tables are 1 byte, so narrow the arguments +to match to ensure min() and max() comparisons without casts. + +Signed-off-by: Mario Limonciello +Acked-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 2 +- + drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 2 +- + drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h | 4 ++-- + drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 4 ++-- + drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 8 ++++---- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 4 ++-- + 6 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +index 222af2fae7458..16c03771c1239 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -1232,7 +1232,7 @@ static int smu_smc_hw_setup(struct smu_context *smu) + { + struct smu_feature *feature = &smu->smu_feature; + struct amdgpu_device *adev = smu->adev; +- uint32_t pcie_gen = 0, pcie_width = 0; ++ uint8_t pcie_gen = 0, pcie_width = 0; + uint64_t features_supported; + int ret = 0; + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +index 6e2069dcb6b9d..d1d7713b97794 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +@@ -856,7 +856,7 @@ struct pptable_funcs { + * &pcie_gen_cap: Maximum allowed PCIe generation. + * &pcie_width_cap: Maximum allowed PCIe width. + */ +- int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); ++ int (*update_pcie_parameters)(struct smu_context *smu, uint8_t pcie_gen_cap, uint8_t pcie_width_cap); + + /** + * @i2c_init: Initialize i2c. +diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +index 355c156d871af..cc02f979e9e98 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h ++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +@@ -296,8 +296,8 @@ int smu_v13_0_get_pptable_from_firmware(struct smu_context *smu, + uint32_t pptable_id); + + int smu_v13_0_update_pcie_parameters(struct smu_context *smu, +- uint32_t pcie_gen_cap, +- uint32_t pcie_width_cap); ++ uint8_t pcie_gen_cap, ++ uint8_t pcie_width_cap); + + #endif + #endif +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +index 95f6d821bacbc..addaa69119b8e 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +@@ -2375,8 +2375,8 @@ static int navi10_get_power_limit(struct smu_context *smu, + } + + static int navi10_update_pcie_parameters(struct smu_context *smu, +- uint32_t pcie_gen_cap, +- uint32_t pcie_width_cap) ++ uint8_t pcie_gen_cap, ++ uint8_t pcie_width_cap) + { + struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; + PPTable_t *pptable = smu->smu_table.driver_pptable; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +index 9119b0df2419f..9a5f3d31e7780 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +@@ -2084,14 +2084,14 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context + #define MAX(a, b) ((a) > (b) ? (a) : (b)) + + static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, +- uint32_t pcie_gen_cap, +- uint32_t pcie_width_cap) ++ uint8_t pcie_gen_cap, ++ uint8_t pcie_width_cap) + { + struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; + struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; + uint8_t *table_member1, *table_member2; +- uint32_t min_gen_speed, max_gen_speed; +- uint32_t min_lane_width, max_lane_width; ++ uint8_t min_gen_speed, max_gen_speed; ++ uint8_t min_lane_width, max_lane_width; + uint32_t smu_pcie_arg; + int ret, i; + +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +index 9b62b45ebb7f0..4fa94f583b87c 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +@@ -2426,8 +2426,8 @@ int smu_v13_0_mode1_reset(struct smu_context *smu) + } + + int smu_v13_0_update_pcie_parameters(struct smu_context *smu, +- uint32_t pcie_gen_cap, +- uint32_t pcie_width_cap) ++ uint8_t pcie_gen_cap, ++ uint8_t pcie_width_cap) + { + struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; + struct smu_13_0_pcie_table *pcie_table = +-- +2.42.0 + diff --git a/queue-6.5/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch b/queue-6.5/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch new file mode 100644 index 00000000000..4797a9d91c1 --- /dev/null +++ b/queue-6.5/drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch @@ -0,0 +1,105 @@ +From 6122cd721b77bcfaa3190c3fd8d606b29a685755 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 12:56:37 +0000 +Subject: drm/amdgpu: Fix a null pointer access when the smc_rreg pointer is + NULL + +From: Qu Huang + +[ Upstream commit 5104fdf50d326db2c1a994f8b35dcd46e63ae4ad ] + +In certain types of chips, such as VEGA20, reading the amdgpu_regs_smc file could result in an abnormal null pointer access when the smc_rreg pointer is NULL. Below are the steps to reproduce this issue and the corresponding exception log: + +1. Navigate to the directory: /sys/kernel/debug/dri/0 +2. Execute command: cat amdgpu_regs_smc +3. Exception Log:: +[4005007.702554] BUG: kernel NULL pointer dereference, address: 0000000000000000 +[4005007.702562] #PF: supervisor instruction fetch in kernel mode +[4005007.702567] #PF: error_code(0x0010) - not-present page +[4005007.702570] PGD 0 P4D 0 +[4005007.702576] Oops: 0010 [#1] SMP NOPTI +[4005007.702581] CPU: 4 PID: 62563 Comm: cat Tainted: G OE 5.15.0-43-generic #46-Ubunt u +[4005007.702590] RIP: 0010:0x0 +[4005007.702598] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6. +[4005007.702600] RSP: 0018:ffffa82b46d27da0 EFLAGS: 00010206 +[4005007.702605] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffa82b46d27e68 +[4005007.702609] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9940656e0000 +[4005007.702612] RBP: ffffa82b46d27dd8 R08: 0000000000000000 R09: ffff994060c07980 +[4005007.702615] R10: 0000000000020000 R11: 0000000000000000 R12: 00007f5e06753000 +[4005007.702618] R13: ffff9940656e0000 R14: ffffa82b46d27e68 R15: 00007f5e06753000 +[4005007.702622] FS: 00007f5e0755b740(0000) GS:ffff99479d300000(0000) knlGS:0000000000000000 +[4005007.702626] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[4005007.702629] CR2: ffffffffffffffd6 CR3: 00000003253fc000 CR4: 00000000003506e0 +[4005007.702633] Call Trace: +[4005007.702636] +[4005007.702640] amdgpu_debugfs_regs_smc_read+0xb0/0x120 [amdgpu] +[4005007.703002] full_proxy_read+0x5c/0x80 +[4005007.703011] vfs_read+0x9f/0x1a0 +[4005007.703019] ksys_read+0x67/0xe0 +[4005007.703023] __x64_sys_read+0x19/0x20 +[4005007.703028] do_syscall_64+0x5c/0xc0 +[4005007.703034] ? do_user_addr_fault+0x1e3/0x670 +[4005007.703040] ? exit_to_user_mode_prepare+0x37/0xb0 +[4005007.703047] ? irqentry_exit_to_user_mode+0x9/0x20 +[4005007.703052] ? irqentry_exit+0x19/0x30 +[4005007.703057] ? exc_page_fault+0x89/0x160 +[4005007.703062] ? asm_exc_page_fault+0x8/0x30 +[4005007.703068] entry_SYSCALL_64_after_hwframe+0x44/0xae +[4005007.703075] RIP: 0033:0x7f5e07672992 +[4005007.703079] Code: c0 e9 b2 fe ff ff 50 48 8d 3d fa b2 0c 00 e8 c5 1d 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 e c 28 48 89 54 24 +[4005007.703083] RSP: 002b:00007ffe03097898 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 +[4005007.703088] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007f5e07672992 +[4005007.703091] RDX: 0000000000020000 RSI: 00007f5e06753000 RDI: 0000000000000003 +[4005007.703094] RBP: 00007f5e06753000 R08: 00007f5e06752010 R09: 00007f5e06752010 +[4005007.703096] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000022000 +[4005007.703099] R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000 +[4005007.703105] +[4005007.703107] Modules linked in: nf_tables libcrc32c nfnetlink algif_hash af_alg binfmt_misc nls_ iso8859_1 ipmi_ssif ast intel_rapl_msr intel_rapl_common drm_vram_helper drm_ttm_helper amd64_edac t tm edac_mce_amd kvm_amd ccp mac_hid k10temp kvm acpi_ipmi ipmi_si rapl sch_fq_codel ipmi_devintf ipm i_msghandler msr parport_pc ppdev lp parport mtd pstore_blk efi_pstore ramoops pstore_zone reed_solo mon ip_tables x_tables autofs4 ib_uverbs ib_core amdgpu(OE) amddrm_ttm_helper(OE) amdttm(OE) iommu_v 2 amd_sched(OE) amdkcl(OE) drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec rc_core drm igb ahci xhci_pci libahci i2c_piix4 i2c_algo_bit xhci_pci_renesas dca +[4005007.703184] CR2: 0000000000000000 +[4005007.703188] ---[ end trace ac65a538d240da39 ]--- +[4005007.800865] RIP: 0010:0x0 +[4005007.800871] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6. +[4005007.800874] RSP: 0018:ffffa82b46d27da0 EFLAGS: 00010206 +[4005007.800878] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffa82b46d27e68 +[4005007.800881] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9940656e0000 +[4005007.800883] RBP: ffffa82b46d27dd8 R08: 0000000000000000 R09: ffff994060c07980 +[4005007.800886] R10: 0000000000020000 R11: 0000000000000000 R12: 00007f5e06753000 +[4005007.800888] R13: ffff9940656e0000 R14: ffffa82b46d27e68 R15: 00007f5e06753000 +[4005007.800891] FS: 00007f5e0755b740(0000) GS:ffff99479d300000(0000) knlGS:0000000000000000 +[4005007.800895] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[4005007.800898] CR2: ffffffffffffffd6 CR3: 00000003253fc000 CR4: 00000000003506e0 + +Signed-off-by: Qu Huang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +index 56e89e76ff179..33cada366eeb1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -747,6 +747,9 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, + ssize_t result = 0; + int r; + ++ if (!adev->smc_rreg) ++ return -EPERM; ++ + if (size & 0x3 || *pos & 0x3) + return -EINVAL; + +@@ -803,6 +806,9 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * + ssize_t result = 0; + int r; + ++ if (!adev->smc_wreg) ++ return -EPERM; ++ + if (size & 0x3 || *pos & 0x3) + return -EINVAL; + +-- +2.42.0 + diff --git a/queue-6.5/drm-amdgpu-fix-potential-null-pointer-derefernce.patch b/queue-6.5/drm-amdgpu-fix-potential-null-pointer-derefernce.patch new file mode 100644 index 00000000000..9ecc241b9d5 --- /dev/null +++ b/queue-6.5/drm-amdgpu-fix-potential-null-pointer-derefernce.patch @@ -0,0 +1,37 @@ +From 1ba3add831c39ce969b3279f7390da656e827cdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 16:22:29 +0800 +Subject: drm/amdgpu: Fix potential null pointer derefernce + +From: Stanley.Yang + +[ Upstream commit 80285ae1ec8717b597b20de38866c29d84d321a1 ] + +The amdgpu_ras_get_context may return NULL if device +not support ras feature, so add check before using. + +Signed-off-by: Stanley.Yang +Reviewed-by: Tao Zhou +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 8940ee73f2dfe..ecc61a6d13e13 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5399,7 +5399,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, + * Flush RAM to disk so that after reboot + * the user can read log and see why the system rebooted. + */ +- if (need_emergency_restart && amdgpu_ras_get_context(adev)->reboot) { ++ if (need_emergency_restart && amdgpu_ras_get_context(adev) && ++ amdgpu_ras_get_context(adev)->reboot) { + DRM_WARN("Emergency reboot."); + + ksys_sync_helper(); +-- +2.42.0 + diff --git a/queue-6.5/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch b/queue-6.5/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch new file mode 100644 index 00000000000..dacae5b18c0 --- /dev/null +++ b/queue-6.5/drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch @@ -0,0 +1,103 @@ +From dafe257c678561faa9e1e0e8cf91f5e0cd27e088 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 19:31:48 -0400 +Subject: drm/amdgpu: fix software pci_unplug on some chips + +From: Vitaly Prosyak + +[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ] + +When software 'pci unplug' using IGT is executed we got a sysfs directory +entry is NULL for differant ras blocks like hdp, umc, etc. +Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group' +check that 'sd' is not NULL. + +[ +0.000001] RIP: 0010:sysfs_remove_group+0x83/0x90 +[ +0.000002] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 +[ +0.000001] RSP: 0018:ffffc90002067c90 EFLAGS: 00010246 +[ +0.000002] RAX: 0000000000000000 RBX: ffffffff824ea180 RCX: 0000000000000000 +[ +0.000001] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[ +0.000001] RBP: ffffc90002067ca8 R08: 0000000000000000 R09: 0000000000000000 +[ +0.000001] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +[ +0.000001] R13: ffff88810a395f48 R14: ffff888101aab0d0 R15: 0000000000000000 +[ +0.000001] FS: 00007f5ddaa43a00(0000) GS:ffff88841e800000(0000) knlGS:0000000000000000 +[ +0.000002] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ +0.000001] CR2: 00007f8ffa61ba50 CR3: 0000000106432000 CR4: 0000000000350ef0 +[ +0.000001] Call Trace: +[ +0.000001] +[ +0.000001] ? show_regs+0x72/0x90 +[ +0.000002] ? sysfs_remove_group+0x83/0x90 +[ +0.000002] ? __warn+0x8d/0x160 +[ +0.000001] ? sysfs_remove_group+0x83/0x90 +[ +0.000001] ? report_bug+0x1bb/0x1d0 +[ +0.000003] ? handle_bug+0x46/0x90 +[ +0.000001] ? exc_invalid_op+0x19/0x80 +[ +0.000002] ? asm_exc_invalid_op+0x1b/0x20 +[ +0.000003] ? sysfs_remove_group+0x83/0x90 +[ +0.000001] dpm_sysfs_remove+0x61/0x70 +[ +0.000002] device_del+0xa3/0x3d0 +[ +0.000002] ? ktime_get_mono_fast_ns+0x46/0xb0 +[ +0.000002] device_unregister+0x18/0x70 +[ +0.000001] i2c_del_adapter+0x26d/0x330 +[ +0.000002] arcturus_i2c_control_fini+0x25/0x50 [amdgpu] +[ +0.000236] smu_sw_fini+0x38/0x260 [amdgpu] +[ +0.000241] amdgpu_device_fini_sw+0x116/0x670 [amdgpu] +[ +0.000186] ? mutex_lock+0x13/0x50 +[ +0.000003] amdgpu_driver_release_kms+0x16/0x40 [amdgpu] +[ +0.000192] drm_minor_release+0x4f/0x80 [drm] +[ +0.000025] drm_release+0xfe/0x150 [drm] +[ +0.000027] __fput+0x9f/0x290 +[ +0.000002] ____fput+0xe/0x20 +[ +0.000002] task_work_run+0x61/0xa0 +[ +0.000002] exit_to_user_mode_prepare+0x150/0x170 +[ +0.000002] syscall_exit_to_user_mode+0x2a/0x50 + +Cc: Hawking Zhang +Cc: Luben Tuikov +Cc: Alex Deucher +Cc: Christian Koenig +Signed-off-by: Vitaly Prosyak +Reviewed-by: Luben Tuikov +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index 7d5019a884024..2003be3390aab 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -1380,7 +1380,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) + { + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + +- sysfs_remove_file_from_group(&adev->dev->kobj, ++ if (adev->dev->kobj.sd) ++ sysfs_remove_file_from_group(&adev->dev->kobj, + &con->badpages_attr.attr, + RAS_FS_NAME); + } +@@ -1397,7 +1398,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct amdgpu_device *adev) + .attrs = attrs, + }; + +- sysfs_remove_group(&adev->dev->kobj, &group); ++ if (adev->dev->kobj.sd) ++ sysfs_remove_group(&adev->dev->kobj, &group); + + return 0; + } +@@ -1444,7 +1446,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev, + if (!obj || !obj->attr_inuse) + return -EINVAL; + +- sysfs_remove_file_from_group(&adev->dev->kobj, ++ if (adev->dev->kobj.sd) ++ sysfs_remove_file_from_group(&adev->dev->kobj, + &obj->sysfs_attr.attr, + RAS_FS_NAME); + obj->attr_inuse = 0; +-- +2.42.0 + diff --git a/queue-6.5/drm-amdgpu-not-to-save-bo-in-the-case-of-ras-err_eve.patch b/queue-6.5/drm-amdgpu-not-to-save-bo-in-the-case-of-ras-err_eve.patch new file mode 100644 index 00000000000..b010e884093 --- /dev/null +++ b/queue-6.5/drm-amdgpu-not-to-save-bo-in-the-case-of-ras-err_eve.patch @@ -0,0 +1,45 @@ +From 7a6ffdaec6885fb7911b1e15c5770001ed72b5cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 16:34:08 -0400 +Subject: drm/amdgpu: not to save bo in the case of RAS err_event_athub + +From: David (Ming Qiang) Wu + +[ Upstream commit fa1f1cc09d588a90c8ce3f507c47df257461d148 ] + +err_event_athub will corrupt VCPU buffer and not good to +be restored in amdgpu_vcn_resume() and in this case +the VCPU buffer needs to be cleared for VCN firmware to +work properly. + +Acked-by: Leo Liu +Signed-off-by: David (Ming Qiang) Wu +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +index ae455aab5d29d..7e54abca45206 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +@@ -292,8 +292,15 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) + void *ptr; + int i, idx; + ++ bool in_ras_intr = amdgpu_ras_intr_triggered(); ++ + cancel_delayed_work_sync(&adev->vcn.idle_work); + ++ /* err_event_athub will corrupt VCPU buffer, so we need to ++ * restore fw data and clear buffer in amdgpu_vcn_resume() */ ++ if (in_ras_intr) ++ return 0; ++ + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + if (adev->vcn.harvest_config & (1 << i)) + continue; +-- +2.42.0 + diff --git a/queue-6.5/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch b/queue-6.5/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch new file mode 100644 index 00000000000..81a5ab615ab --- /dev/null +++ b/queue-6.5/drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch @@ -0,0 +1,37 @@ +From ee9a4ffd70e43cfa2d7dcba3362a65b9da078784 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 09:53:43 +0800 +Subject: drm/amdgpu/vkms: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit cd90511557fdfb394bb4ac4c3b539b007383914c ] + +In amdgpu_vkms_conn_get_modes(), the return value of drm_cvt_mode() +is assigned to mode, which will lead to a NULL pointer dereference +on failure of drm_cvt_mode(). Add a check to avoid null pointer +dereference. + +Signed-off-by: Ma Ke +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +index d0748bcfad16b..75d25fba80821 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +@@ -239,6 +239,8 @@ static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector) + + for (i = 0; i < ARRAY_SIZE(common_modes); i++) { + mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); ++ if (!mode) ++ continue; + drm_mode_probed_add(connector, mode); + } + +-- +2.42.0 + diff --git a/queue-6.5/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch b/queue-6.5/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch new file mode 100644 index 00000000000..d9e25cf00fa --- /dev/null +++ b/queue-6.5/drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch @@ -0,0 +1,48 @@ +From 429e669105c91df639c94d249e2a1b880a7bcf17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 11:20:28 -0500 +Subject: drm/amdkfd: Fix a race condition of vram buffer unref in svm code + +From: Xiaogang Chen + +[ Upstream commit 709c348261618da7ed89d6c303e2ceb9e453ba74 ] + +prange->svm_bo unref can happen in both mmu callback and a callback after +migrate to system ram. Both are async call in different tasks. Sync svm_bo +unref operation to avoid random "use-after-free". + +Signed-off-by: Xiaogang Chen +Reviewed-by: Philip Yang +Reviewed-by: Jesse Zhang +Tested-by: Jesse Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index 50f943e04f8a4..e1d73a7223675 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -617,8 +617,15 @@ svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange, + + void svm_range_vram_node_free(struct svm_range *prange) + { +- svm_range_bo_unref(prange->svm_bo); +- prange->ttm_res = NULL; ++ /* serialize prange->svm_bo unref */ ++ mutex_lock(&prange->lock); ++ /* prange->svm_bo has not been unref */ ++ if (prange->ttm_res) { ++ prange->ttm_res = NULL; ++ mutex_unlock(&prange->lock); ++ svm_range_bo_unref(prange->svm_bo); ++ } else ++ mutex_unlock(&prange->lock); + } + + struct kfd_node * +-- +2.42.0 + diff --git a/queue-6.5/drm-amdkfd-fix-shift-out-of-bounds-issue.patch b/queue-6.5/drm-amdkfd-fix-shift-out-of-bounds-issue.patch new file mode 100644 index 00000000000..f5a505c86cf --- /dev/null +++ b/queue-6.5/drm-amdkfd-fix-shift-out-of-bounds-issue.patch @@ -0,0 +1,60 @@ +From d08bb7ad033157cbbcb65e9974646831d05983eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 09:43:51 +0800 +Subject: drm/amdkfd: Fix shift out-of-bounds issue + +From: Jesse Zhang + +[ Upstream commit 282c1d793076c2edac6c3db51b7e8ed2b41d60a5 ] + +[ 567.613292] shift exponent 255 is too large for 64-bit type 'long unsigned int' +[ 567.614498] CPU: 5 PID: 238 Comm: kworker/5:1 Tainted: G OE 6.2.0-34-generic #34~22.04.1-Ubuntu +[ 567.614502] Hardware name: AMD Splinter/Splinter-RPL, BIOS WS43927N_871 09/25/2023 +[ 567.614504] Workqueue: events send_exception_work_handler [amdgpu] +[ 567.614748] Call Trace: +[ 567.614750] +[ 567.614753] dump_stack_lvl+0x48/0x70 +[ 567.614761] dump_stack+0x10/0x20 +[ 567.614763] __ubsan_handle_shift_out_of_bounds+0x156/0x310 +[ 567.614769] ? srso_alias_return_thunk+0x5/0x7f +[ 567.614773] ? update_sd_lb_stats.constprop.0+0xf2/0x3c0 +[ 567.614780] svm_range_split_by_granularity.cold+0x2b/0x34 [amdgpu] +[ 567.615047] ? srso_alias_return_thunk+0x5/0x7f +[ 567.615052] svm_migrate_to_ram+0x185/0x4d0 [amdgpu] +[ 567.615286] do_swap_page+0x7b6/0xa30 +[ 567.615291] ? srso_alias_return_thunk+0x5/0x7f +[ 567.615294] ? __free_pages+0x119/0x130 +[ 567.615299] handle_pte_fault+0x227/0x280 +[ 567.615303] __handle_mm_fault+0x3c0/0x720 +[ 567.615311] handle_mm_fault+0x119/0x330 +[ 567.615314] ? lock_mm_and_find_vma+0x44/0x250 +[ 567.615318] do_user_addr_fault+0x1a9/0x640 +[ 567.615323] exc_page_fault+0x81/0x1b0 +[ 567.615328] asm_exc_page_fault+0x27/0x30 +[ 567.615332] RIP: 0010:__get_user_8+0x1c/0x30 + +Signed-off-by: Jesse Zhang +Suggested-by: Philip Yang +Reviewed-by: Yifan Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index e1d73a7223675..a5c394fcbb350 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -756,7 +756,7 @@ svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange, + prange->flags &= ~attrs[i].value; + break; + case KFD_IOCTL_SVM_ATTR_GRANULARITY: +- prange->granularity = attrs[i].value; ++ prange->granularity = min_t(uint32_t, attrs[i].value, 0x3F); + break; + default: + WARN_ONCE(1, "svm_range_check_attrs wasn't called?"); +-- +2.42.0 + diff --git a/queue-6.5/drm-amdkfd-ratelimited-sq-interrupt-messages.patch b/queue-6.5/drm-amdkfd-ratelimited-sq-interrupt-messages.patch new file mode 100644 index 00000000000..944b70902b9 --- /dev/null +++ b/queue-6.5/drm-amdkfd-ratelimited-sq-interrupt-messages.patch @@ -0,0 +1,118 @@ +From fa4e9d7844287bdf2e45279585b8b2c4d6760bf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Aug 2023 12:10:57 -0400 +Subject: drm/amdkfd: ratelimited SQ interrupt messages + +From: Harish Kasiviswanathan + +[ Upstream commit 37fb87910724f21a1f27a75743d4f9accdee77fb ] + +No functional change. Use ratelimited version of pr_ to avoid +overflowing of dmesg buffer + +Signed-off-by: Harish Kasiviswanathan +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c | 6 +++--- + drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++--- + drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 6 +++--- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c +index c7991e07b6be5..a7697ec8188e0 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c +@@ -268,7 +268,7 @@ static void event_interrupt_wq_v10(struct kfd_node *dev, + SQ_INTERRUPT_WORD_WAVE_CTXID1, ENCODING); + switch (encoding) { + case SQ_INTERRUPT_WORD_ENCODING_AUTO: +- pr_debug( ++ pr_debug_ratelimited( + "sq_intr: auto, se %d, ttrace %d, wlt %d, ttrac_buf0_full %d, ttrac_buf1_full %d, ttrace_utc_err %d\n", + REG_GET_FIELD(context_id1, SQ_INTERRUPT_WORD_AUTO_CTXID1, + SE_ID), +@@ -284,7 +284,7 @@ static void event_interrupt_wq_v10(struct kfd_node *dev, + THREAD_TRACE_UTC_ERROR)); + break; + case SQ_INTERRUPT_WORD_ENCODING_INST: +- pr_debug("sq_intr: inst, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n", ++ pr_debug_ratelimited("sq_intr: inst, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n", + REG_GET_FIELD(context_id1, SQ_INTERRUPT_WORD_WAVE_CTXID1, + SE_ID), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0, +@@ -310,7 +310,7 @@ static void event_interrupt_wq_v10(struct kfd_node *dev, + case SQ_INTERRUPT_WORD_ENCODING_ERROR: + sq_intr_err_type = REG_GET_FIELD(context_id0, KFD_CTXID0, + ERR_TYPE); +- pr_warn("sq_intr: error, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d, err_type %d\n", ++ pr_warn_ratelimited("sq_intr: error, se %d, data 0x%x, sa %d, priv %d, wave_id %d, simd_id %d, wgp_id %d, err_type %d\n", + REG_GET_FIELD(context_id1, SQ_INTERRUPT_WORD_WAVE_CTXID1, + SE_ID), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0, +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c +index f933bd231fb9c..2a65792fd1162 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c +@@ -150,7 +150,7 @@ enum SQ_INTERRUPT_ERROR_TYPE { + + static void print_sq_intr_info_auto(uint32_t context_id0, uint32_t context_id1) + { +- pr_debug( ++ pr_debug_ratelimited( + "sq_intr: auto, ttrace %d, wlt %d, ttrace_buf_full %d, reg_tms %d, cmd_tms %d, host_cmd_ovf %d, host_reg_ovf %d, immed_ovf %d, ttrace_utc_err %d\n", + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID0, THREAD_TRACE), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID0, WLT), +@@ -165,7 +165,7 @@ static void print_sq_intr_info_auto(uint32_t context_id0, uint32_t context_id1) + + static void print_sq_intr_info_inst(uint32_t context_id0, uint32_t context_id1) + { +- pr_debug( ++ pr_debug_ratelimited( + "sq_intr: inst, data 0x%08x, sh %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n", + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0, DATA), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID0, SH_ID), +@@ -177,7 +177,7 @@ static void print_sq_intr_info_inst(uint32_t context_id0, uint32_t context_id1) + + static void print_sq_intr_info_error(uint32_t context_id0, uint32_t context_id1) + { +- pr_warn( ++ pr_warn_ratelimited( + "sq_intr: error, detail 0x%08x, type %d, sh %d, priv %d, wave_id %d, simd_id %d, wgp_id %d\n", + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_ERROR_CTXID0, DETAIL), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_ERROR_CTXID0, TYPE), +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +index f0731a6a5306c..02695ccd22d6e 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +@@ -333,7 +333,7 @@ static void event_interrupt_wq_v9(struct kfd_node *dev, + encoding = REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, ENCODING); + switch (encoding) { + case SQ_INTERRUPT_WORD_ENCODING_AUTO: +- pr_debug( ++ pr_debug_ratelimited( + "sq_intr: auto, se %d, ttrace %d, wlt %d, ttrac_buf_full %d, reg_tms %d, cmd_tms %d, host_cmd_ovf %d, host_reg_ovf %d, immed_ovf %d, ttrace_utc_err %d\n", + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, SE_ID), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE), +@@ -347,7 +347,7 @@ static void event_interrupt_wq_v9(struct kfd_node *dev, + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE_UTC_ERROR)); + break; + case SQ_INTERRUPT_WORD_ENCODING_INST: +- pr_debug("sq_intr: inst, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, intr_data 0x%x\n", ++ pr_debug_ratelimited("sq_intr: inst, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, intr_data 0x%x\n", + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SE_ID), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, DATA), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SH_ID), +@@ -366,7 +366,7 @@ static void event_interrupt_wq_v9(struct kfd_node *dev, + break; + case SQ_INTERRUPT_WORD_ENCODING_ERROR: + sq_intr_err = REG_GET_FIELD(sq_int_data, KFD_SQ_INT_DATA, ERR_TYPE); +- pr_warn("sq_intr: error, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, err_type %d\n", ++ pr_warn_ratelimited("sq_intr: error, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, err_type %d\n", + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SE_ID), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, DATA), + REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SH_ID), +-- +2.42.0 + diff --git a/queue-6.5/drm-edid-fixup-h-vsync_end-instead-of-h-vtotal.patch b/queue-6.5/drm-edid-fixup-h-vsync_end-instead-of-h-vtotal.patch new file mode 100644 index 00000000000..f58844df130 --- /dev/null +++ b/queue-6.5/drm-edid-fixup-h-vsync_end-instead-of-h-vtotal.patch @@ -0,0 +1,94 @@ +From ba5de37ad7d869934accb32d6683073f2ebe62c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 00:19:33 +0300 +Subject: drm/edid: Fixup h/vsync_end instead of h/vtotal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +[ Upstream commit 2682768bde745b10ae126a322cdcaf532cf88851 ] + +There are some weird EDIDs floating around that have the sync +pulse extending beyond the end of the blanking period. + +On the currently problemtic machine (HP Omni 120) EDID reports +the following mode: +"1600x900": 60 108000 1600 1780 1860 1800 900 910 913 1000 0x40 0x5 +which is then "corrected" to have htotal=1861 by the current drm_edid.c +code. + +The fixup code was originally added in commit 7064fef56369 ("drm: work +around EDIDs with bad htotal/vtotal values"). Googling around we end up in +https://bugs.launchpad.net/ubuntu/hardy/+source/xserver-xorg-video-intel/+bug/297245 +where we find an EDID for a Dell Studio 15, which reports: +(II) VESA(0): clock: 65.0 MHz Image Size: 331 x 207 mm +(II) VESA(0): h_active: 1280 h_sync: 1328 h_sync_end 1360 h_blank_end 1337 h_border: 0 +(II) VESA(0): v_active: 800 v_sync: 803 v_sync_end 809 v_blanking: 810 v_border: 0 + +Note that if we use the hblank size (as opposed of the hsync_end) +from the DTD to determine htotal we get exactly 60Hz refresh rate in +both cases, whereas using hsync_end to determine htotal we get a +slightly lower refresh rates. This makes me believe the using the +hblank size is what was intended even in those cases. + +Also note that in case of the HP Onmi 120 the VBIOS boots with these: + crtc timings: 108000 1600 1780 1860 1800 900 910 913 1000, type: 0x40 flags: 0x5 +ie. it just blindly stuffs the bogus hsync_end and htotal from the DTD +into the transcoder timing registers, and the display works. I believe +the (at least more modern) hardware will automagically terminate the hsync +pulse when the timing generator reaches htotal, which again points that we +should use the hblank size to determine htotal. Unfortunatley the old bug +reports for the Dell machines are extremely lacking in useful details so +we have no idea what kind of timings the VBIOS programmed into the +hardware :( + +Let's just flip this quirk around and reduce the length of the sync +pulse instead of extending the blanking period. This at least seems +to be the correct thing to do on more modern hardware. And if any +issues crop up on older hardware we need to debug them properly. + +v2: Add debug message breadcrumbs (Jani) + +Reviewed-by: Jani Nikula +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8895 +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20230920211934.14920-1-ville.syrjala@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_edid.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 69d855123d3e3..f1ceb7d08519e 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -3499,11 +3499,19 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto + mode->vsync_end = mode->vsync_start + vsync_pulse_width; + mode->vtotal = mode->vdisplay + vblank; + +- /* Some EDIDs have bogus h/vtotal values */ +- if (mode->hsync_end > mode->htotal) +- mode->htotal = mode->hsync_end + 1; +- if (mode->vsync_end > mode->vtotal) +- mode->vtotal = mode->vsync_end + 1; ++ /* Some EDIDs have bogus h/vsync_end values */ ++ if (mode->hsync_end > mode->htotal) { ++ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] reducing hsync_end %d->%d\n", ++ connector->base.id, connector->name, ++ mode->hsync_end, mode->htotal); ++ mode->hsync_end = mode->htotal; ++ } ++ if (mode->vsync_end > mode->vtotal) { ++ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] reducing vsync_end %d->%d\n", ++ connector->base.id, connector->name, ++ mode->vsync_end, mode->vtotal); ++ mode->vsync_end = mode->vtotal; ++ } + + drm_mode_do_interlace_quirk(mode, pt); + +-- +2.42.0 + diff --git a/queue-6.5/drm-gma500-fix-call-trace-when-psb_gem_mm_init-fails.patch b/queue-6.5/drm-gma500-fix-call-trace-when-psb_gem_mm_init-fails.patch new file mode 100644 index 00000000000..8bdfd99f4db --- /dev/null +++ b/queue-6.5/drm-gma500-fix-call-trace-when-psb_gem_mm_init-fails.patch @@ -0,0 +1,138 @@ +From 485e8897aaba422ec5022d2c3d44756bf28f8e62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Jul 2023 02:58:55 +0800 +Subject: drm/gma500: Fix call trace when psb_gem_mm_init() fails + +From: Sui Jingfeng + +[ Upstream commit da596080b2b400c50fe9f8f237bcaf09fed06af8 ] + +Because the gma_irq_install() is call after psb_gem_mm_init() function, +when psb_gem_mm_init() fails, the interrupt line haven't been allocated. +Yet the gma_irq_uninstall() is called in the psb_driver_unload() function +without checking if checking the irq is registered or not. + +The calltrace is appended as following: + +[ 20.539253] ioremap memtype_reserve failed -16 +[ 20.543895] gma500 0000:00:02.0: Failure to map stolen base. +[ 20.565049] ------------[ cut here ]------------ +[ 20.565066] Trying to free already-free IRQ 16 +[ 20.565087] WARNING: CPU: 1 PID: 381 at kernel/irq/manage.c:1893 free_irq+0x209/0x370 +[ 20.565316] CPU: 1 PID: 381 Comm: systemd-udevd Tainted: G C 6.5.0-rc1+ #368 +[ 20.565329] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./IMB-140D Plus, BIOS P1.10 11/18/2013 +[ 20.565338] RIP: 0010:free_irq+0x209/0x370 +[ 20.565357] Code: 41 5d 41 5e 41 5f 5d 31 d2 89 d1 89 d6 89 d7 41 89 d1 c3 cc cc cc cc 8b 75 d0 48 c7 c7 e0 77 12 9f 4c 89 4d c8 e8 57 fe f4 ff <0f> 0b 48 8b 75 c8 4c 89 f7 e8 29 f3 f1 00 49 8b 47 40 48 8b 40 78 +[ 20.565369] RSP: 0018:ffffae3b40733808 EFLAGS: 00010046 +[ 20.565382] RAX: 0000000000000000 RBX: ffff9f8082bfe000 RCX: 0000000000000000 +[ 20.565390] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[ 20.565397] RBP: ffffae3b40733840 R08: 0000000000000000 R09: 0000000000000000 +[ 20.565405] R10: 0000000000000000 R11: 0000000000000000 R12: ffff9f80871c3100 +[ 20.565413] R13: ffff9f80835d3360 R14: ffff9f80835d32a4 R15: ffff9f80835d3200 +[ 20.565424] FS: 00007f13d36458c0(0000) GS:ffff9f8138880000(0000) knlGS:0000000000000000 +[ 20.565434] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 20.565441] CR2: 00007f0d046f3f20 CR3: 0000000006c8c000 CR4: 00000000000006e0 +[ 20.565450] Call Trace: +[ 20.565458] +[ 20.565470] ? show_regs+0x72/0x90 +[ 20.565488] ? free_irq+0x209/0x370 +[ 20.565504] ? __warn+0x8d/0x160 +[ 20.565520] ? free_irq+0x209/0x370 +[ 20.565536] ? report_bug+0x1bb/0x1d0 +[ 20.565555] ? handle_bug+0x46/0x90 +[ 20.565572] ? exc_invalid_op+0x19/0x80 +[ 20.565587] ? asm_exc_invalid_op+0x1b/0x20 +[ 20.565607] ? free_irq+0x209/0x370 +[ 20.565625] ? free_irq+0x209/0x370 +[ 20.565644] gma_irq_uninstall+0x15b/0x1e0 [gma500_gfx] +[ 20.565728] psb_driver_unload+0x27/0x190 [gma500_gfx] +[ 20.565800] psb_pci_probe+0x5d2/0x790 [gma500_gfx] +[ 20.565873] local_pci_probe+0x48/0xb0 +[ 20.565892] pci_device_probe+0xc8/0x280 +[ 20.565912] really_probe+0x1d2/0x440 +[ 20.565929] __driver_probe_device+0x8a/0x190 +[ 20.565944] driver_probe_device+0x23/0xd0 +[ 20.565957] __driver_attach+0x10f/0x220 +[ 20.565971] ? __pfx___driver_attach+0x10/0x10 +[ 20.565984] bus_for_each_dev+0x7a/0xe0 +[ 20.566002] driver_attach+0x1e/0x30 +[ 20.566014] bus_add_driver+0x127/0x240 +[ 20.566029] driver_register+0x64/0x140 +[ 20.566043] ? __pfx_psb_init+0x10/0x10 [gma500_gfx] +[ 20.566111] __pci_register_driver+0x68/0x80 +[ 20.566128] psb_init+0x2c/0xff0 [gma500_gfx] +[ 20.566194] do_one_initcall+0x46/0x330 +[ 20.566214] ? kmalloc_trace+0x2a/0xb0 +[ 20.566233] do_init_module+0x6a/0x270 +[ 20.566250] load_module+0x207f/0x23a0 +[ 20.566278] init_module_from_file+0x9c/0xf0 +[ 20.566293] ? init_module_from_file+0x9c/0xf0 +[ 20.566315] idempotent_init_module+0x184/0x240 +[ 20.566335] __x64_sys_finit_module+0x64/0xd0 +[ 20.566352] do_syscall_64+0x59/0x90 +[ 20.566366] ? ksys_mmap_pgoff+0x123/0x270 +[ 20.566378] ? __secure_computing+0x9b/0x110 +[ 20.566392] ? exit_to_user_mode_prepare+0x39/0x190 +[ 20.566406] ? syscall_exit_to_user_mode+0x2a/0x50 +[ 20.566420] ? do_syscall_64+0x69/0x90 +[ 20.566433] ? do_syscall_64+0x69/0x90 +[ 20.566445] ? do_syscall_64+0x69/0x90 +[ 20.566458] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 +[ 20.566472] RIP: 0033:0x7f13d351ea3d +[ 20.566485] Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c3 a3 0f 00 f7 d8 64 89 01 48 +[ 20.566496] RSP: 002b:00007ffe566c1fd8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 +[ 20.566510] RAX: ffffffffffffffda RBX: 000055e66806eec0 RCX: 00007f13d351ea3d +[ 20.566519] RDX: 0000000000000000 RSI: 00007f13d36d9441 RDI: 0000000000000010 +[ 20.566527] RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000002 +[ 20.566535] R10: 0000000000000010 R11: 0000000000000246 R12: 00007f13d36d9441 +[ 20.566543] R13: 000055e6681108c0 R14: 000055e66805ba70 R15: 000055e66819a9c0 +[ 20.566559] +[ 20.566566] ---[ end trace 0000000000000000 ]--- + +Signed-off-by: Sui Jingfeng +Signed-off-by: Patrik Jakobsson +Link: https://patchwork.freedesktop.org/patch/msgid/20230727185855.713318-1-suijingfeng@loongson.cn +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/gma500/psb_drv.h | 1 + + drivers/gpu/drm/gma500/psb_irq.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h +index f7f709df99b49..70d9adafa2333 100644 +--- a/drivers/gpu/drm/gma500/psb_drv.h ++++ b/drivers/gpu/drm/gma500/psb_drv.h +@@ -424,6 +424,7 @@ struct drm_psb_private { + uint32_t pipestat[PSB_NUM_PIPE]; + + spinlock_t irqmask_lock; ++ bool irq_enabled; + + /* Power */ + bool pm_initialized; +diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c +index 343c51250207d..7bbb79b0497d8 100644 +--- a/drivers/gpu/drm/gma500/psb_irq.c ++++ b/drivers/gpu/drm/gma500/psb_irq.c +@@ -327,6 +327,8 @@ int gma_irq_install(struct drm_device *dev) + + gma_irq_postinstall(dev); + ++ dev_priv->irq_enabled = true; ++ + return 0; + } + +@@ -337,6 +339,9 @@ void gma_irq_uninstall(struct drm_device *dev) + unsigned long irqflags; + unsigned int i; + ++ if (!dev_priv->irq_enabled) ++ return; ++ + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + if (dev_priv->ops->hotplug_enable) +-- +2.42.0 + diff --git a/queue-6.5/drm-i915-mtl-avoid-stringop-overflow-warning.patch b/queue-6.5/drm-i915-mtl-avoid-stringop-overflow-warning.patch new file mode 100644 index 00000000000..29e1b740c15 --- /dev/null +++ b/queue-6.5/drm-i915-mtl-avoid-stringop-overflow-warning.patch @@ -0,0 +1,76 @@ +From 5996b52ba61525f8a3fd4fd4d3118a34e478a01a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 22:10:04 +0200 +Subject: drm/i915/mtl: avoid stringop-overflow warning + +From: Arnd Bergmann + +[ Upstream commit 390001d648ffa027b750b7dceb5d43f4c1d1a39e ] + +The newly added memset() causes a warning for some reason I could not +figure out: + +In file included from arch/x86/include/asm/string.h:3, + from drivers/gpu/drm/i915/gt/intel_rc6.c:6: +In function 'rc6_res_reg_init', + inlined from 'intel_rc6_init' at drivers/gpu/drm/i915/gt/intel_rc6.c:610:2: +arch/x86/include/asm/string_32.h:195:29: error: '__builtin_memset' writing 16 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=] + 195 | #define memset(s, c, count) __builtin_memset(s, c, count) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/gpu/drm/i915/gt/intel_rc6.c:584:9: note: in expansion of macro 'memset' + 584 | memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg)); + | ^~~~~~ +In function 'intel_rc6_init': + +Change it to an normal initializer and an added memcpy() that does not have +this problem. + +Fixes: 4bb9ca7ee074 ("drm/i915/mtl: C6 residency and C state type for MTL SAMedia") +Signed-off-by: Arnd Bergmann +Reviewed-by: Jani Nikula +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20231016201012.1022812-1-arnd@kernel.org +(cherry picked from commit 0520b30b219053cd789909bca45b3c486ef3ee09) +Signed-off-by: Jani Nikula +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/intel_rc6.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c +index 58bb1c55294c9..ccdc1afbf11b5 100644 +--- a/drivers/gpu/drm/i915/gt/intel_rc6.c ++++ b/drivers/gpu/drm/i915/gt/intel_rc6.c +@@ -584,19 +584,23 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6) + + static void rc6_res_reg_init(struct intel_rc6 *rc6) + { +- memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg)); ++ i915_reg_t res_reg[INTEL_RC6_RES_MAX] = { ++ [0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG, ++ }; + + switch (rc6_to_gt(rc6)->type) { + case GT_MEDIA: +- rc6->res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6; ++ res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6; + break; + default: +- rc6->res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED; +- rc6->res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6; +- rc6->res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p; +- rc6->res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp; ++ res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED; ++ res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6; ++ res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p; ++ res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp; + break; + } ++ ++ memcpy(rc6->res_reg, res_reg, sizeof(res_reg)); + } + + void intel_rc6_init(struct intel_rc6 *rc6) +-- +2.42.0 + diff --git a/queue-6.5/drm-i915-tc-fix-wformat-truncation-in-intel_tc_port_.patch b/queue-6.5/drm-i915-tc-fix-wformat-truncation-in-intel_tc_port_.patch new file mode 100644 index 00000000000..193afcadd31 --- /dev/null +++ b/queue-6.5/drm-i915-tc-fix-wformat-truncation-in-intel_tc_port_.patch @@ -0,0 +1,85 @@ +From 573d32dc746063da10c32fab1409746344ffba22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 14:56:36 +0200 +Subject: drm/i915/tc: Fix -Wformat-truncation in intel_tc_port_init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nirmoy Das + +[ Upstream commit 9506fba463fcbdf8c8b7af3ec9ee34360df843fe ] + +Fix below compiler warning: + +intel_tc.c:1879:11: error: ‘%d’ directive output may be truncated +writing between 1 and 11 bytes into a region of size 3 +[-Werror=format-truncation=] +"%c/TC#%d", port_name(port), tc_port + 1); + ^~ +intel_tc.c:1878:2: note: ‘snprintf’ output between 7 and 17 bytes +into a destination of size 8 + snprintf(tc->port_name, sizeof(tc->port_name), + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + "%c/TC#%d", port_name(port), tc_port + 1); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +v2: use kasprintf(Imre) +v3: use const for port_name, and fix tc mem leak(Imre) + +Fixes: 3eafcddf766b ("drm/i915/tc: Move TC port fields to a new intel_tc_port struct") +Cc: Mika Kahola +Cc: Imre Deak +Cc: Jani Nikula +Signed-off-by: Nirmoy Das +Reviewed-by: Andrzej Hajda +Reviewed-by: Imre Deak +Reviewed-by: Mika Kahola +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20231026125636.5080-1-nirmoy.das@intel.com +(cherry picked from commit 70a3cbbe620ee66afb0c066624196077767e61b2) +Signed-off-by: Jani Nikula +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/display/intel_tc.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c +index 3ebf41859043e..cdf2455440bea 100644 +--- a/drivers/gpu/drm/i915/display/intel_tc.c ++++ b/drivers/gpu/drm/i915/display/intel_tc.c +@@ -58,7 +58,7 @@ struct intel_tc_port { + struct delayed_work link_reset_work; + int link_refcount; + bool legacy_port:1; +- char port_name[8]; ++ const char *port_name; + enum tc_port_mode mode; + enum tc_port_mode init_mode; + enum phy_fia phy_fia; +@@ -1841,8 +1841,12 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) + else + tc->phy_ops = &icl_tc_phy_ops; + +- snprintf(tc->port_name, sizeof(tc->port_name), +- "%c/TC#%d", port_name(port), tc_port + 1); ++ tc->port_name = kasprintf(GFP_KERNEL, "%c/TC#%d", port_name(port), ++ tc_port + 1); ++ if (!tc->port_name) { ++ kfree(tc); ++ return -ENOMEM; ++ } + + mutex_init(&tc->lock); + /* TODO: Combine the two works */ +@@ -1863,6 +1867,7 @@ void intel_tc_port_cleanup(struct intel_digital_port *dig_port) + { + intel_tc_port_suspend(dig_port); + ++ kfree(dig_port->tc->port_name); + kfree(dig_port->tc); + dig_port->tc = NULL; + } +-- +2.42.0 + diff --git a/queue-6.5/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch b/queue-6.5/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch new file mode 100644 index 00000000000..d41e753fb31 --- /dev/null +++ b/queue-6.5/drm-komeda-drop-all-currently-held-locks-if-deadlock.patch @@ -0,0 +1,184 @@ +From a3442fe18d1c83e8d5a4003a15a641f13251b893 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 10:05:53 +0800 +Subject: drm/komeda: drop all currently held locks if deadlock happens + +From: baozhu.liu + +[ Upstream commit 19ecbe8325a2a7ffda5ff4790955b84eaccba49f ] + +If komeda_pipeline_unbound_components() returns -EDEADLK, +it means that a deadlock happened in the locking context. +Currently, komeda is not dealing with the deadlock properly,producing the +following output when CONFIG_DEBUG_WW_MUTEX_SLOWPATH is enabled: + + ------------[ cut here ]------------ +[ 26.103984] WARNING: CPU: 2 PID: 345 at drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c:1248 + komeda_release_unclaimed_resources+0x13c/0x170 +[ 26.117453] Modules linked in: +[ 26.120511] CPU: 2 PID: 345 Comm: composer@2.1-se Kdump: loaded Tainted: G W 5.10.110-SE-SDK1.8-dirty #16 +[ 26.131374] Hardware name: Siengine Se1000 Evaluation board (DT) +[ 26.137379] pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--) +[ 26.143385] pc : komeda_release_unclaimed_resources+0x13c/0x170 +[ 26.149301] lr : komeda_release_unclaimed_resources+0xbc/0x170 +[ 26.155130] sp : ffff800017b8b8d0 +[ 26.158442] pmr_save: 000000e0 +[ 26.161493] x29: ffff800017b8b8d0 x28: ffff000cf2f96200 +[ 26.166805] x27: ffff000c8f5a8800 x26: 0000000000000000 +[ 26.172116] x25: 0000000000000038 x24: ffff8000116a0140 +[ 26.177428] x23: 0000000000000038 x22: ffff000cf2f96200 +[ 26.182739] x21: ffff000cfc300300 x20: ffff000c8ab77080 +[ 26.188051] x19: 0000000000000003 x18: 0000000000000000 +[ 26.193362] x17: 0000000000000000 x16: 0000000000000000 +[ 26.198672] x15: b400e638f738ba38 x14: 0000000000000000 +[ 26.203983] x13: 0000000106400a00 x12: 0000000000000000 +[ 26.209294] x11: 0000000000000000 x10: 0000000000000000 +[ 26.214604] x9 : ffff800012f80000 x8 : ffff000ca3308000 +[ 26.219915] x7 : 0000000ff3000000 x6 : ffff80001084034c +[ 26.225226] x5 : ffff800017b8bc40 x4 : 000000000000000f +[ 26.230536] x3 : ffff000ca3308000 x2 : 0000000000000000 +[ 26.235847] x1 : 0000000000000000 x0 : ffffffffffffffdd +[ 26.241158] Call trace: +[ 26.243604] komeda_release_unclaimed_resources+0x13c/0x170 +[ 26.249175] komeda_crtc_atomic_check+0x68/0xf0 +[ 26.253706] drm_atomic_helper_check_planes+0x138/0x1f4 +[ 26.258929] komeda_kms_check+0x284/0x36c +[ 26.262939] drm_atomic_check_only+0x40c/0x714 +[ 26.267381] drm_atomic_nonblocking_commit+0x1c/0x60 +[ 26.272344] drm_mode_atomic_ioctl+0xa3c/0xb8c +[ 26.276787] drm_ioctl_kernel+0xc4/0x120 +[ 26.280708] drm_ioctl+0x268/0x534 +[ 26.284109] __arm64_sys_ioctl+0xa8/0xf0 +[ 26.288030] el0_svc_common.constprop.0+0x80/0x240 +[ 26.292817] do_el0_svc+0x24/0x90 +[ 26.296132] el0_svc+0x20/0x30 +[ 26.299185] el0_sync_handler+0xe8/0xf0 +[ 26.303018] el0_sync+0x1a4/0x1c0 +[ 26.306330] irq event stamp: 0 +[ 26.309384] hardirqs last enabled at (0): [<0000000000000000>] 0x0 +[ 26.315650] hardirqs last disabled at (0): [] copy_process+0x5d0/0x183c +[ 26.323825] softirqs last enabled at (0): [] copy_process+0x5d0/0x183c +[ 26.331997] softirqs last disabled at (0): [<0000000000000000>] 0x0 +[ 26.338261] ---[ end trace 20ae984fa860184a ]--- +[ 26.343021] ------------[ cut here ]------------ +[ 26.347646] WARNING: CPU: 3 PID: 345 at drivers/gpu/drm/drm_modeset_lock.c:228 drm_modeset_drop_locks+0x84/0x90 +[ 26.357727] Modules linked in: +[ 26.360783] CPU: 3 PID: 345 Comm: composer@2.1-se Kdump: loaded Tainted: G W 5.10.110-SE-SDK1.8-dirty #16 +[ 26.371645] Hardware name: Siengine Se1000 Evaluation board (DT) +[ 26.377647] pstate: 20400009 (nzCv daif +PAN -UAO -TCO BTYPE=--) +[ 26.383649] pc : drm_modeset_drop_locks+0x84/0x90 +[ 26.388351] lr : drm_mode_atomic_ioctl+0x860/0xb8c +[ 26.393137] sp : ffff800017b8bb10 +[ 26.396447] pmr_save: 000000e0 +[ 26.399497] x29: ffff800017b8bb10 x28: 0000000000000001 +[ 26.404807] x27: 0000000000000038 x26: 0000000000000002 +[ 26.410115] x25: ffff000cecbefa00 x24: ffff000cf2f96200 +[ 26.415423] x23: 0000000000000001 x22: 0000000000000018 +[ 26.420731] x21: 0000000000000001 x20: ffff800017b8bc10 +[ 26.426039] x19: 0000000000000000 x18: 0000000000000000 +[ 26.431347] x17: 0000000002e8bf2c x16: 0000000002e94c6b +[ 26.436655] x15: 0000000002ea48b9 x14: ffff8000121f0300 +[ 26.441963] x13: 0000000002ee2ca8 x12: ffff80001129cae0 +[ 26.447272] x11: ffff800012435000 x10: ffff000ed46b5e88 +[ 26.452580] x9 : ffff000c9935e600 x8 : 0000000000000000 +[ 26.457888] x7 : 000000008020001e x6 : 000000008020001f +[ 26.463196] x5 : ffff80001085fbe0 x4 : fffffe0033a59f20 +[ 26.468504] x3 : 000000008020001e x2 : 0000000000000000 +[ 26.473813] x1 : 0000000000000000 x0 : ffff000c8f596090 +[ 26.479122] Call trace: +[ 26.481566] drm_modeset_drop_locks+0x84/0x90 +[ 26.485918] drm_mode_atomic_ioctl+0x860/0xb8c +[ 26.490359] drm_ioctl_kernel+0xc4/0x120 +[ 26.494278] drm_ioctl+0x268/0x534 +[ 26.497677] __arm64_sys_ioctl+0xa8/0xf0 +[ 26.501598] el0_svc_common.constprop.0+0x80/0x240 +[ 26.506384] do_el0_svc+0x24/0x90 +[ 26.509697] el0_svc+0x20/0x30 +[ 26.512748] el0_sync_handler+0xe8/0xf0 +[ 26.516580] el0_sync+0x1a4/0x1c0 +[ 26.519891] irq event stamp: 0 +[ 26.522943] hardirqs last enabled at (0): [<0000000000000000>] 0x0 +[ 26.529207] hardirqs last disabled at (0): [] copy_process+0x5d0/0x183c +[ 26.537379] softirqs last enabled at (0): [] copy_process+0x5d0/0x183c +[ 26.545550] softirqs last disabled at (0): [<0000000000000000>] 0x0 +[ 26.551812] ---[ end trace 20ae984fa860184b ]--- + +According to the call trace information,it can be located to be +WARN_ON(IS_ERR(c_st)) in the komeda_pipeline_unbound_components function; +Then follow the function. +komeda_pipeline_unbound_components +-> komeda_component_get_state_and_set_user + -> komeda_pipeline_get_state_and_set_crtc + -> komeda_pipeline_get_state + ->drm_atomic_get_private_obj_state + -> drm_atomic_get_private_obj_state + -> drm_modeset_lock + +komeda_pipeline_unbound_components +-> komeda_component_get_state_and_set_user + -> komeda_component_get_state + -> drm_atomic_get_private_obj_state + -> drm_modeset_lock + +ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); if (ret) + return ERR_PTR(ret); +Here it return -EDEADLK. + +deal with the deadlock as suggested by [1], using the +function drm_modeset_backoff(). +[1] https://docs.kernel.org/gpu/drm-kms.html?highlight=kms#kms-locking + +Therefore, handling this problem can be solved +by adding return -EDEADLK back to the drm_modeset_backoff processing flow +in the drm_mode_atomic_ioctl function. + +Signed-off-by: baozhu.liu +Signed-off-by: menghui.huang +Reviewed-by: Liviu Dudau +Signed-off-by: Liviu Dudau +Link: https://patchwork.freedesktop.org/patch/msgid/20230804013117.6870-1-menghui.huang@siengine.com +Signed-off-by: Sasha Levin +--- + .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +index 3276a3e82c628..916f2c36bf2f7 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +@@ -1223,7 +1223,7 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, + return 0; + } + +-static void ++static int + komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, + struct komeda_pipeline_state *new) + { +@@ -1243,8 +1243,12 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, + c = komeda_pipeline_get_component(pipe, id); + c_st = komeda_component_get_state_and_set_user(c, + drm_st, NULL, new->crtc); ++ if (PTR_ERR(c_st) == -EDEADLK) ++ return -EDEADLK; + WARN_ON(IS_ERR(c_st)); + } ++ ++ return 0; + } + + /* release unclaimed pipeline resource */ +@@ -1266,9 +1270,8 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, + if (WARN_ON(IS_ERR_OR_NULL(st))) + return -EINVAL; + +- komeda_pipeline_unbound_components(pipe, st); ++ return komeda_pipeline_unbound_components(pipe, st); + +- return 0; + } + + /* Since standalone disabled components must be disabled separately and in the +-- +2.42.0 + diff --git a/queue-6.5/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch b/queue-6.5/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch new file mode 100644 index 00000000000..313ae39f98b --- /dev/null +++ b/queue-6.5/drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch @@ -0,0 +1,79 @@ +From 6ea1c6eaede7f0d5ea6cc1d5601a162dec95ce96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 17:20:34 +0300 +Subject: drm/msm/dp: skip validity check for DP CTS EDID checksum + +From: Jani Nikula + +[ Upstream commit a251c9d8e30833b260101edb9383b176ee2b7cb1 ] + +The DP CTS test for EDID last block checksum expects the checksum for +the last block, invalid or not. Skip the validity check. + +For the most part (*), the EDIDs returned by drm_get_edid() will be +valid anyway, and there's the CTS workaround to get the checksum for +completely invalid EDIDs. See commit 7948fe12d47a ("drm/msm/dp: return +correct edid checksum after corrupted edid checksum read"). + +This lets us remove one user of drm_edid_block_valid() with hopes the +function can be removed altogether in the future. + +(*) drm_get_edid() ignores checksum errors on CTA extensions. + +Cc: Abhinav Kumar +Cc: Dmitry Baryshkov +Cc: Kuogee Hsieh +Cc: Marijn Suijten +Cc: Rob Clark +Cc: Sean Paul +Cc: Stephen Boyd +Cc: linux-arm-msm@vger.kernel.org +Cc: freedreno@lists.freedesktop.org +Signed-off-by: Jani Nikula +Reviewed-by: Stephen Boyd +Reviewed-by: Abhinav Kumar +Reviewed-by: Kuogee Hsieh +Patchwork: https://patchwork.freedesktop.org/patch/555361/ +Link: https://lore.kernel.org/r/20230901142034.580802-1-jani.nikula@intel.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/dp/dp_panel.c | 21 ++------------------- + 1 file changed, 2 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c +index 42d52510ffd4a..86a8e06c7a60f 100644 +--- a/drivers/gpu/drm/msm/dp/dp_panel.c ++++ b/drivers/gpu/drm/msm/dp/dp_panel.c +@@ -289,26 +289,9 @@ int dp_panel_get_modes(struct dp_panel *dp_panel, + + static u8 dp_panel_get_edid_checksum(struct edid *edid) + { +- struct edid *last_block; +- u8 *raw_edid; +- bool is_edid_corrupt = false; ++ edid += edid->extensions; + +- if (!edid) { +- DRM_ERROR("invalid edid input\n"); +- return 0; +- } +- +- raw_edid = (u8 *)edid; +- raw_edid += (edid->extensions * EDID_LENGTH); +- last_block = (struct edid *)raw_edid; +- +- /* block type extension */ +- drm_edid_block_valid(raw_edid, 1, false, &is_edid_corrupt); +- if (!is_edid_corrupt) +- return last_block->checksum; +- +- DRM_ERROR("Invalid block, no checksum\n"); +- return 0; ++ return edid->checksum; + } + + void dp_panel_handle_sink_request(struct dp_panel *dp_panel) +-- +2.42.0 + diff --git a/queue-6.5/drm-panel-fix-a-possible-null-pointer-dereference.patch b/queue-6.5/drm-panel-fix-a-possible-null-pointer-dereference.patch new file mode 100644 index 00000000000..80b0b78c2f8 --- /dev/null +++ b/queue-6.5/drm-panel-fix-a-possible-null-pointer-dereference.patch @@ -0,0 +1,39 @@ +From de45dc7103d31dc457751dd71d3f1451e0e9b30f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 7 Oct 2023 11:31:05 +0800 +Subject: drm/panel: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit 924e5814d1f84e6fa5cb19c6eceb69f066225229 ] + +In versatile_panel_get_modes(), the return value of drm_mode_duplicate() +is assigned to mode, which will lead to a NULL pointer dereference +on failure of drm_mode_duplicate(). Add a check to avoid npd. + +Signed-off-by: Ma Ke +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20231007033105.3997998-1-make_ruc2021@163.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20231007033105.3997998-1-make_ruc2021@163.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-arm-versatile.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panel/panel-arm-versatile.c b/drivers/gpu/drm/panel/panel-arm-versatile.c +index abb0788843c60..503ecea72c5ea 100644 +--- a/drivers/gpu/drm/panel/panel-arm-versatile.c ++++ b/drivers/gpu/drm/panel/panel-arm-versatile.c +@@ -267,6 +267,8 @@ static int versatile_panel_get_modes(struct drm_panel *panel, + connector->display_info.bus_flags = vpanel->panel_type->bus_flags; + + mode = drm_mode_duplicate(connector->dev, &vpanel->panel_type->mode); ++ if (!mode) ++ return -ENOMEM; + drm_mode_set_name(mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + +-- +2.42.0 + diff --git a/queue-6.5/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch b/queue-6.5/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch new file mode 100644 index 00000000000..516fd579f13 --- /dev/null +++ b/queue-6.5/drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch @@ -0,0 +1,39 @@ +From dee686ec578c97904a61baeb2386430622404e98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 17:04:46 +0800 +Subject: drm/panel/panel-tpo-tpg110: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit f22def5970c423ea7f87d5247bd0ef91416b0658 ] + +In tpg110_get_modes(), the return value of drm_mode_duplicate() is +assigned to mode, which will lead to a NULL pointer dereference on +failure of drm_mode_duplicate(). Add a check to avoid npd. + +Signed-off-by: Ma Ke +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20231009090446.4043798-1-make_ruc2021@163.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20231009090446.4043798-1-make_ruc2021@163.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-tpo-tpg110.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panel/panel-tpo-tpg110.c b/drivers/gpu/drm/panel/panel-tpo-tpg110.c +index 845304435e235..f6a212e542cb9 100644 +--- a/drivers/gpu/drm/panel/panel-tpo-tpg110.c ++++ b/drivers/gpu/drm/panel/panel-tpo-tpg110.c +@@ -379,6 +379,8 @@ static int tpg110_get_modes(struct drm_panel *panel, + connector->display_info.bus_flags = tpg->panel_mode->bus_flags; + + mode = drm_mode_duplicate(connector->dev, &tpg->panel_mode->mode); ++ if (!mode) ++ return -ENOMEM; + drm_mode_set_name(mode); + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + +-- +2.42.0 + diff --git a/queue-6.5/drm-panel-st7703-pick-different-reset-sequence.patch b/queue-6.5/drm-panel-st7703-pick-different-reset-sequence.patch new file mode 100644 index 00000000000..187db7ebac6 --- /dev/null +++ b/queue-6.5/drm-panel-st7703-pick-different-reset-sequence.patch @@ -0,0 +1,86 @@ +From af135ba0aa53734edf4bd7f4a7919282e33f5614 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Feb 2023 18:17:48 +0100 +Subject: drm/panel: st7703: Pick different reset sequence +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ondrej Jirman + +[ Upstream commit d12d635bb03c7cb4830acb641eb176ee9ff2aa89 ] + +Switching to a different reset sequence, enabling IOVCC before enabling +VCC. + +There also needs to be a delay after enabling the supplies and before +deasserting the reset. The datasheet specifies 1ms after the supplies +reach the required voltage. Use 10-20ms to also give the power supplies +some time to reach the required voltage, too. + +This fixes intermittent panel initialization failures and screen +corruption during resume from sleep on panel xingbangda,xbd599 (e.g. +used in PinePhone). + +Signed-off-by: Ondrej Jirman +Signed-off-by: Frank Oltmanns +Reported-by: Samuel Holland +Reviewed-by: Guido Günther +Tested-by: Guido Günther +Signed-off-by: Guido Günther +Link: https://patchwork.freedesktop.org/patch/msgid/20230211171748.36692-2-frank@oltmanns.dev +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-sitronix-st7703.c | 25 ++++++++++--------- + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c +index 3aa31f3d61574..687749bbec62c 100644 +--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c ++++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c +@@ -506,29 +506,30 @@ static int st7703_prepare(struct drm_panel *panel) + return 0; + + dev_dbg(ctx->dev, "Resetting the panel\n"); +- ret = regulator_enable(ctx->vcc); ++ gpiod_set_value_cansleep(ctx->reset_gpio, 1); ++ ++ ret = regulator_enable(ctx->iovcc); + if (ret < 0) { +- dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); ++ dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); + return ret; + } +- ret = regulator_enable(ctx->iovcc); ++ ++ ret = regulator_enable(ctx->vcc); + if (ret < 0) { +- dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); +- goto disable_vcc; ++ dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); ++ regulator_disable(ctx->iovcc); ++ return ret; + } + +- gpiod_set_value_cansleep(ctx->reset_gpio, 1); +- usleep_range(20, 40); ++ /* Give power supplies time to stabilize before deasserting reset. */ ++ usleep_range(10000, 20000); ++ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); +- msleep(20); ++ usleep_range(15000, 20000); + + ctx->prepared = true; + + return 0; +- +-disable_vcc: +- regulator_disable(ctx->vcc); +- return ret; + } + + static const u32 mantix_bus_formats[] = { +-- +2.42.0 + diff --git a/queue-6.5/drm-qxl-prevent-memory-leak.patch b/queue-6.5/drm-qxl-prevent-memory-leak.patch new file mode 100644 index 00000000000..a1db16e0f17 --- /dev/null +++ b/queue-6.5/drm-qxl-prevent-memory-leak.patch @@ -0,0 +1,41 @@ +From 2621eb1e64217c10970b0125b02145114e268d31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 10:53:09 +0800 +Subject: drm/qxl: prevent memory leak + +From: Zongmin Zhou + +[ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ] + +The allocated memory for qdev->dumb_heads should be released +in qxl_destroy_monitors_object before qxl suspend. +otherwise,qxl_create_monitors_object will be called to +reallocate memory for qdev->dumb_heads after qxl resume, +it will cause memory leak. + +Signed-off-by: Zongmin Zhou +Link: https://lore.kernel.org/r/20230801025309.4049813-1-zhouzongmin@kylinos.cn +Reviewed-by: Dave Airlie +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/qxl/qxl_display.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c +index 6492a70e3c396..404b0483bb7cb 100644 +--- a/drivers/gpu/drm/qxl/qxl_display.c ++++ b/drivers/gpu/drm/qxl/qxl_display.c +@@ -1229,6 +1229,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) + if (!qdev->monitors_config_bo) + return 0; + ++ kfree(qdev->dumb_heads); ++ qdev->dumb_heads = NULL; ++ + qdev->monitors_config = NULL; + qdev->ram_header->monitors_config = 0; + +-- +2.42.0 + diff --git a/queue-6.5/drm-radeon-fix-a-possible-null-pointer-dereference.patch b/queue-6.5/drm-radeon-fix-a-possible-null-pointer-dereference.patch new file mode 100644 index 00000000000..ab8322962d6 --- /dev/null +++ b/queue-6.5/drm-radeon-fix-a-possible-null-pointer-dereference.patch @@ -0,0 +1,37 @@ +From 0c2ff34042e1d4267eacb2d8b0ca2c6c95200a0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 09:21:43 +0800 +Subject: drm/radeon: fix a possible null pointer dereference + +From: Ma Ke + +[ Upstream commit 2c1fe3c480f9e1deefd50d4b18be4a046011ee1f ] + +In radeon_tv_get_modes(), the return value of drm_cvt_mode() +is assigned to mode, which will lead to a NULL pointer +dereference on failure of drm_cvt_mode(). Add a check to +avoid null point dereference. + +Signed-off-by: Ma Ke +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/radeon_connectors.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index 07193cd0c4174..4859d965d67e3 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -1122,6 +1122,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) + else { + /* only 800x600 is supported right now on pre-avivo chips */ + tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); ++ if (!tv_mode) ++ return 0; + tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, tv_mode); + } +-- +2.42.0 + diff --git a/queue-6.5/drm-vmwgfx_surface.c-copy-user-array-safely.patch b/queue-6.5/drm-vmwgfx_surface.c-copy-user-array-safely.patch new file mode 100644 index 00000000000..6c4aa97770f --- /dev/null +++ b/queue-6.5/drm-vmwgfx_surface.c-copy-user-array-safely.patch @@ -0,0 +1,44 @@ +From 46fdd2efa64ccecc6b6a1e14b077c55be3433230 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:13 +0200 +Subject: drm: vmwgfx_surface.c: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit 06ab64a0d836ac430c5f94669710a78aa43942cb ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-7-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index 3829be282ff00..17463aeeef28f 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -774,9 +774,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + sizeof(metadata->mip_levels)); + metadata->num_sizes = num_sizes; + metadata->sizes = +- memdup_user((struct drm_vmw_size __user *)(unsigned long) ++ memdup_array_user((struct drm_vmw_size __user *)(unsigned long) + req->size_addr, +- sizeof(*metadata->sizes) * metadata->num_sizes); ++ metadata->num_sizes, sizeof(*metadata->sizes)); + if (IS_ERR(metadata->sizes)) { + ret = PTR_ERR(metadata->sizes); + goto out_no_sizes; +-- +2.42.0 + diff --git a/queue-6.5/drm_lease.c-copy-user-array-safely.patch b/queue-6.5/drm_lease.c-copy-user-array-safely.patch new file mode 100644 index 00000000000..577e3de345f --- /dev/null +++ b/queue-6.5/drm_lease.c-copy-user-array-safely.patch @@ -0,0 +1,43 @@ +From 07d975bb6aa15d8eea7690103fbb57e5b9218201 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:12 +0200 +Subject: drm_lease.c: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit f37d63e219c39199a59b8b8a211412ff27192830 ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-6-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_lease.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c +index 150fe15550680..94375c6a54256 100644 +--- a/drivers/gpu/drm/drm_lease.c ++++ b/drivers/gpu/drm/drm_lease.c +@@ -510,8 +510,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, + /* Handle leased objects, if any */ + idr_init(&leases); + if (object_count != 0) { +- object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), +- array_size(object_count, sizeof(__u32))); ++ object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids), ++ object_count, sizeof(__u32)); + if (IS_ERR(object_ids)) { + ret = PTR_ERR(object_ids); + idr_destroy(&leases); +-- +2.42.0 + diff --git a/queue-6.5/dt-bindings-phy-qcom-snps-eusb2-repeater-add-magic-t.patch b/queue-6.5/dt-bindings-phy-qcom-snps-eusb2-repeater-add-magic-t.patch new file mode 100644 index 00000000000..e6d03c6fa1d --- /dev/null +++ b/queue-6.5/dt-bindings-phy-qcom-snps-eusb2-repeater-add-magic-t.patch @@ -0,0 +1,62 @@ +From 0305a5387807251400681fe8f8f9bf1212740660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 11:53:23 +0200 +Subject: dt-bindings: phy: qcom,snps-eusb2-repeater: Add magic tuning + overrides + +From: Konrad Dybcio + +[ Upstream commit c20b59b2996c89c4f072c3312e6210528a298330 ] + +The EUSB2 repeater requires some alterations to its init sequence, +depending on board design. + +Add support for making the necessary changes to that sequence to make USB +functional on SM8550-based Xperia 1 V. + +They all have lackluster description due to lack of information. + +Signed-off-by: Konrad Dybcio +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20230830-topic-eusb2_override-v2-1-7d8c893d93f6@linaro.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + .../phy/qcom,snps-eusb2-repeater.yaml | 21 +++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml +index 083fda530b484..828650d4c4b09 100644 +--- a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml ++++ b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml +@@ -27,6 +27,27 @@ properties: + + vdd3-supply: true + ++ qcom,tune-usb2-disc-thres: ++ $ref: /schemas/types.yaml#/definitions/uint8 ++ description: High-Speed disconnect threshold ++ minimum: 0 ++ maximum: 7 ++ default: 0 ++ ++ qcom,tune-usb2-amplitude: ++ $ref: /schemas/types.yaml#/definitions/uint8 ++ description: High-Speed trasmit amplitude ++ minimum: 0 ++ maximum: 15 ++ default: 8 ++ ++ qcom,tune-usb2-preem: ++ $ref: /schemas/types.yaml#/definitions/uint8 ++ description: High-Speed TX pre-emphasis tuning ++ minimum: 0 ++ maximum: 7 ++ default: 5 ++ + required: + - compatible + - reg +-- +2.42.0 + diff --git a/queue-6.5/dt-bindings-serial-fix-regex-pattern-for-matching-se.patch b/queue-6.5/dt-bindings-serial-fix-regex-pattern-for-matching-se.patch new file mode 100644 index 00000000000..5a23ed6da12 --- /dev/null +++ b/queue-6.5/dt-bindings-serial-fix-regex-pattern-for-matching-se.patch @@ -0,0 +1,42 @@ +From 6957f3303a954117f7a29a7507a154eeed13b2a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 11:32:46 +0200 +Subject: dt-bindings: serial: fix regex pattern for matching serial node + children + +From: Krzysztof Kozlowski + +[ Upstream commit 42851dfd4dbe38e34724a00063a9fad5cfc48dcd ] + +The regular expression pattern for matching serial node children should +accept only nodes starting and ending with the set of words: bluetooth, +gnss, gps or mcu. Add missing brackets to enforce such matching. + +Fixes: 0c559bc8abfb ("dt-bindings: serial: restrict possible child node names") +Reported-by: Andreas Kemnade +Closes: https://lore.kernel.org/all/20231004170021.36b32465@aktux/ +Signed-off-by: Krzysztof Kozlowski +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20231005093247.128166-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/serial/serial.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Documentation/devicetree/bindings/serial/serial.yaml b/Documentation/devicetree/bindings/serial/serial.yaml +index ea277560a5966..5727bd549deca 100644 +--- a/Documentation/devicetree/bindings/serial/serial.yaml ++++ b/Documentation/devicetree/bindings/serial/serial.yaml +@@ -96,7 +96,7 @@ then: + rts-gpios: false + + patternProperties: +- "^bluetooth|gnss|gps|mcu$": ++ "^(bluetooth|gnss|gps|mcu)$": + if: + type: object + then: +-- +2.42.0 + diff --git a/queue-6.5/exfat-support-handle-zero-size-directory.patch b/queue-6.5/exfat-support-handle-zero-size-directory.patch new file mode 100644 index 00000000000..5011c54204c --- /dev/null +++ b/queue-6.5/exfat-support-handle-zero-size-directory.patch @@ -0,0 +1,103 @@ +From ffc9cb9c05d1eb262d785cd7b71a1d77f4b912ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jul 2023 14:23:08 +0800 +Subject: exfat: support handle zero-size directory + +From: Yuezhang Mo + +[ Upstream commit dab48b8f2fe7264d51ec9eed0adea0fe3c78830a ] + +After repairing a corrupted file system with exfatprogs' fsck.exfat, +zero-size directories may result. It is also possible to create +zero-size directories in other exFAT implementation, such as Paragon +ufsd dirver. + +As described in the specification, the lower directory size limits +is 0 bytes. + +Without this commit, sub-directories and files cannot be created +under a zero-size directory, and it cannot be removed. + +Signed-off-by: Yuezhang Mo +Reviewed-by: Andy Wu +Reviewed-by: Aoyama Wataru +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/namei.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index e0ff9d156f6f5..43774693f65f5 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -351,14 +351,20 @@ static int exfat_find_empty_entry(struct inode *inode, + if (exfat_check_max_dentries(inode)) + return -ENOSPC; + +- /* we trust p_dir->size regardless of FAT type */ +- if (exfat_find_last_cluster(sb, p_dir, &last_clu)) +- return -EIO; +- + /* + * Allocate new cluster to this directory + */ +- exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); ++ if (ei->start_clu != EXFAT_EOF_CLUSTER) { ++ /* we trust p_dir->size regardless of FAT type */ ++ if (exfat_find_last_cluster(sb, p_dir, &last_clu)) ++ return -EIO; ++ ++ exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); ++ } else { ++ /* This directory is empty */ ++ exfat_chain_set(&clu, EXFAT_EOF_CLUSTER, 0, ++ ALLOC_NO_FAT_CHAIN); ++ } + + /* allocate a cluster */ + ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode)); +@@ -368,6 +374,11 @@ static int exfat_find_empty_entry(struct inode *inode, + if (exfat_zeroed_cluster(inode, clu.dir)) + return -EIO; + ++ if (ei->start_clu == EXFAT_EOF_CLUSTER) { ++ ei->start_clu = clu.dir; ++ p_dir->dir = clu.dir; ++ } ++ + /* append to the FAT chain */ + if (clu.flags != p_dir->flags) { + /* no-fat-chain bit is disabled, +@@ -646,7 +657,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + info->type = exfat_get_entry_type(ep); + info->attr = le16_to_cpu(ep->dentry.file.attr); + info->size = le64_to_cpu(ep2->dentry.stream.valid_size); +- if ((info->type == TYPE_FILE) && (info->size == 0)) { ++ if (info->size == 0) { + info->flags = ALLOC_NO_FAT_CHAIN; + info->start_clu = EXFAT_EOF_CLUSTER; + } else { +@@ -890,6 +901,9 @@ static int exfat_check_dir_empty(struct super_block *sb, + + dentries_per_clu = sbi->dentries_per_clu; + ++ if (p_dir->dir == EXFAT_EOF_CLUSTER) ++ return 0; ++ + exfat_chain_dup(&clu, p_dir); + + while (clu.dir != EXFAT_EOF_CLUSTER) { +@@ -1257,7 +1271,8 @@ static int __exfat_rename(struct inode *old_parent_inode, + } + + /* Free the clusters if new_inode is a dir(as if exfat_rmdir) */ +- if (new_entry_type == TYPE_DIR) { ++ if (new_entry_type == TYPE_DIR && ++ new_ei->start_clu != EXFAT_EOF_CLUSTER) { + /* new_ei, new_clu_to_free */ + struct exfat_chain new_clu_to_free; + +-- +2.42.0 + diff --git a/queue-6.5/f2fs-fix-error-handling-of-__get_node_page.patch b/queue-6.5/f2fs-fix-error-handling-of-__get_node_page.patch new file mode 100644 index 00000000000..de8c58ded2e --- /dev/null +++ b/queue-6.5/f2fs-fix-error-handling-of-__get_node_page.patch @@ -0,0 +1,36 @@ +From 79bd55a7254f972393d99902f5283dedfc5bc7b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 14:51:02 +0800 +Subject: f2fs: fix error handling of __get_node_page + +From: Zhiguo Niu + +[ Upstream commit 9b4c8dd99fe48721410741651d426015e03a4b7a ] + +Use f2fs_handle_error to record inconsistent node block error +and return -EFSCORRUPTED instead of -EINVAL. + +Signed-off-by: Zhiguo Niu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/node.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c +index 248764badcde8..ed963c56ac32a 100644 +--- a/fs/f2fs/node.c ++++ b/fs/f2fs/node.c +@@ -1467,7 +1467,8 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid, + ofs_of_node(page), cpver_of_node(page), + next_blkaddr_of_node(page)); + set_sbi_flag(sbi, SBI_NEED_FSCK); +- err = -EINVAL; ++ f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER); ++ err = -EFSCORRUPTED; + out_err: + ClearPageUptodate(page); + out_put_err: +-- +2.42.0 + diff --git a/queue-6.5/f2fs-fix-error-path-of-__f2fs_build_free_nids.patch b/queue-6.5/f2fs-fix-error-path-of-__f2fs_build_free_nids.patch new file mode 100644 index 00000000000..66a473be6ee --- /dev/null +++ b/queue-6.5/f2fs-fix-error-path-of-__f2fs_build_free_nids.patch @@ -0,0 +1,70 @@ +From e4c8aaa5cff85b0a5a6cc3155f2cbadb2629f763 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Oct 2023 19:27:31 +0800 +Subject: f2fs: fix error path of __f2fs_build_free_nids + +From: Zhiguo Niu + +[ Upstream commit a5e80e18f268ea7c7a36bc4159de0deb3b5a2171 ] + +If NAT is corrupted, let scan_nat_page() return EFSCORRUPTED, so that, +caller can set SBI_NEED_FSCK flag into checkpoint for later repair by +fsck. + +Also, this patch introduces a new fscorrupted error flag, and in above +scenario, it will persist the error flag into superblock synchronously +to avoid it has no luck to trigger a checkpoint to record SBI_NEED_FSCK + +Signed-off-by: Zhiguo Niu +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/node.c | 11 +++++++++-- + include/linux/f2fs_fs.h | 1 + + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c +index ee2e1dd64f256..248764badcde8 100644 +--- a/fs/f2fs/node.c ++++ b/fs/f2fs/node.c +@@ -2389,7 +2389,7 @@ static int scan_nat_page(struct f2fs_sb_info *sbi, + blk_addr = le32_to_cpu(nat_blk->entries[i].block_addr); + + if (blk_addr == NEW_ADDR) +- return -EINVAL; ++ return -EFSCORRUPTED; + + if (blk_addr == NULL_ADDR) { + add_free_nid(sbi, start_nid, true, true); +@@ -2504,7 +2504,14 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, + + if (ret) { + f2fs_up_read(&nm_i->nat_tree_lock); +- f2fs_err(sbi, "NAT is corrupt, run fsck to fix it"); ++ ++ if (ret == -EFSCORRUPTED) { ++ f2fs_err(sbi, "NAT is corrupt, run fsck to fix it"); ++ set_sbi_flag(sbi, SBI_NEED_FSCK); ++ f2fs_handle_error(sbi, ++ ERROR_INCONSISTENT_NAT); ++ } ++ + return ret; + } + } +diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h +index a82a4bb6ce68b..cf1adceb02697 100644 +--- a/include/linux/f2fs_fs.h ++++ b/include/linux/f2fs_fs.h +@@ -104,6 +104,7 @@ enum f2fs_error { + ERROR_CORRUPTED_VERITY_XATTR, + ERROR_CORRUPTED_XATTR, + ERROR_INVALID_NODE_REFERENCE, ++ ERROR_INCONSISTENT_NAT, + ERROR_MAX, + }; + +-- +2.42.0 + diff --git a/queue-6.5/fs-jfs-add-check-for-negative-db_l2nbperpage.patch b/queue-6.5/fs-jfs-add-check-for-negative-db_l2nbperpage.patch new file mode 100644 index 00000000000..32fb41a6451 --- /dev/null +++ b/queue-6.5/fs-jfs-add-check-for-negative-db_l2nbperpage.patch @@ -0,0 +1,46 @@ +From 58937452953f913c257067d3b567b311aeecaded Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 17:56:58 +0800 +Subject: fs/jfs: Add check for negative db_l2nbperpage + +From: Juntong Deng + +[ Upstream commit 525b861a008143048535011f3816d407940f4bfa ] + +l2nbperpage is log2(number of blks per page), and the minimum legal +value should be 0, not negative. + +In the case of l2nbperpage being negative, an error will occur +when subsequently used as shift exponent. + +Syzbot reported this bug: + +UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:799:12 +shift exponent -16777216 is negative + +Reported-by: syzbot+debee9ab7ae2b34b0307@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=debee9ab7ae2b34b0307 +Signed-off-by: Juntong Deng +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 88afd108c2dd2..3a1842348112d 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap) + bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); + + bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); +- if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { ++ if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE || ++ bmp->db_l2nbperpage < 0) { + err = -EINVAL; + goto err_release_metapage; + } +-- +2.42.0 + diff --git a/queue-6.5/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch b/queue-6.5/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch new file mode 100644 index 00000000000..4ad25fd1dbf --- /dev/null +++ b/queue-6.5/fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch @@ -0,0 +1,50 @@ +From 6ef488e5478765388e0dd0e73f3452f5244c4f3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 02:06:41 +0800 +Subject: fs/jfs: Add validity check for db_maxag and db_agpref + +From: Juntong Deng + +[ Upstream commit 64933ab7b04881c6c18b21ff206c12278341c72e ] + +Both db_maxag and db_agpref are used as the index of the +db_agfree array, but there is currently no validity check for +db_maxag and db_agpref, which can lead to errors. + +The following is related bug reported by Syzbot: + +UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dmap.c:639:20 +index 7936 is out of range for type 'atomic_t[128]' + +Add checking that the values of db_maxag and db_agpref are valid +indexes for the db_agfree array. + +Reported-by: syzbot+38e876a8aa44b7115c76@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=38e876a8aa44b7115c76 +Signed-off-by: Juntong Deng +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 3a1842348112d..4d59373f9e6c9 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -195,6 +195,12 @@ int dbMount(struct inode *ipbmap) + bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); + bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); + bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); ++ if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 || ++ bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) { ++ err = -EINVAL; ++ goto err_release_metapage; ++ } ++ + bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); + bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); + bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); +-- +2.42.0 + diff --git a/queue-6.5/gcc-plugins-randstruct-only-warn-about-true-flexible.patch b/queue-6.5/gcc-plugins-randstruct-only-warn-about-true-flexible.patch new file mode 100644 index 00000000000..fcf514f1c3b --- /dev/null +++ b/queue-6.5/gcc-plugins-randstruct-only-warn-about-true-flexible.patch @@ -0,0 +1,68 @@ +From f339446de391ebb8f3298aa3501c486f915624bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Nov 2023 13:43:37 -0700 +Subject: gcc-plugins: randstruct: Only warn about true flexible arrays + +From: Kees Cook + +[ Upstream commit 1ee60356c2dca938362528404af95b8ef3e49b6a ] + +The randstruct GCC plugin tried to discover "fake" flexible arrays +to issue warnings about them in randomized structs. In the future +LSM overhead reduction series, it would be legal to have a randomized +struct with a 1-element array, and this should _not_ be treated as a +flexible array, especially since commit df8fc4e934c1 ("kbuild: Enable +-fstrict-flex-arrays=3"). Disable the 0-sized and 1-element array +discovery logic in the plugin, but keep the "true" flexible array check. + +Cc: KP Singh +Cc: linux-hardening@vger.kernel.org +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202311021532.iBwuZUZ0-lkp@intel.com/ +Fixes: df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") +Reviewed-by: Bill Wendling +Acked-by: "Gustavo A. R. Silva" +Link: https://lore.kernel.org/r/20231104204334.work.160-kees@kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + scripts/gcc-plugins/randomize_layout_plugin.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c +index 951b74ba1b242..5e5744b65f8a9 100644 +--- a/scripts/gcc-plugins/randomize_layout_plugin.c ++++ b/scripts/gcc-plugins/randomize_layout_plugin.c +@@ -273,8 +273,6 @@ static bool is_flexible_array(const_tree field) + { + const_tree fieldtype; + const_tree typesize; +- const_tree elemtype; +- const_tree elemsize; + + fieldtype = TREE_TYPE(field); + typesize = TYPE_SIZE(fieldtype); +@@ -282,20 +280,12 @@ static bool is_flexible_array(const_tree field) + if (TREE_CODE(fieldtype) != ARRAY_TYPE) + return false; + +- elemtype = TREE_TYPE(fieldtype); +- elemsize = TYPE_SIZE(elemtype); +- + /* size of type is represented in bits */ + + if (typesize == NULL_TREE && TYPE_DOMAIN(fieldtype) != NULL_TREE && + TYPE_MAX_VALUE(TYPE_DOMAIN(fieldtype)) == NULL_TREE) + return true; + +- if (typesize != NULL_TREE && +- (TREE_CONSTANT(typesize) && (!tree_to_uhwi(typesize) || +- tree_to_uhwi(typesize) == tree_to_uhwi(elemsize)))) +- return true; +- + return false; + } + +-- +2.42.0 + diff --git a/queue-6.5/gfs2-fix-an-oops-in-gfs2_permission.patch b/queue-6.5/gfs2-fix-an-oops-in-gfs2_permission.patch new file mode 100644 index 00000000000..8accaf76b89 --- /dev/null +++ b/queue-6.5/gfs2-fix-an-oops-in-gfs2_permission.patch @@ -0,0 +1,67 @@ +From b9c3ee8a3d11651c2312446d1f635ba027610f2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 03:33:44 +0100 +Subject: gfs2: fix an oops in gfs2_permission + +From: Al Viro + +[ Upstream commit 0abd1557e21c617bd13fc18f7725fc6363c05913 ] + +In RCU mode, we might race with gfs2_evict_inode(), which zeroes +->i_gl. Freeing of the object it points to is RCU-delayed, so +if we manage to fetch the pointer before it's been replaced with +NULL, we are fine. Check if we'd fetched NULL and treat that +as "bail out and tell the caller to get out of RCU mode". + +Signed-off-by: Al Viro +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/inode.c | 11 +++++++++-- + fs/gfs2/super.c | 2 +- + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 17c994a0c0d09..117b4b5a03072 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1862,14 +1862,21 @@ int gfs2_permission(struct mnt_idmap *idmap, struct inode *inode, + { + struct gfs2_inode *ip; + struct gfs2_holder i_gh; ++ struct gfs2_glock *gl; + int error; + + gfs2_holder_mark_uninitialized(&i_gh); + ip = GFS2_I(inode); +- if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { ++ gl = rcu_dereference(ip->i_gl); ++ if (unlikely(!gl)) { ++ /* inode is getting torn down, must be RCU mode */ ++ WARN_ON_ONCE(!(mask & MAY_NOT_BLOCK)); ++ return -ECHILD; ++ } ++ if (gfs2_glock_is_locked_by_me(gl) == NULL) { + if (mask & MAY_NOT_BLOCK) + return -ECHILD; +- error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); ++ error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + } +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index 9f4d5d6549ee6..f98ddb9d19a21 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1558,7 +1558,7 @@ static void gfs2_evict_inode(struct inode *inode) + wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE); + gfs2_glock_add_to_lru(ip->i_gl); + gfs2_glock_put_eventually(ip->i_gl); +- ip->i_gl = NULL; ++ rcu_assign_pointer(ip->i_gl, NULL); + } + } + +-- +2.42.0 + diff --git a/queue-6.5/gfs2-ignore-negated-quota-changes.patch b/queue-6.5/gfs2-ignore-negated-quota-changes.patch new file mode 100644 index 00000000000..8f9c400f566 --- /dev/null +++ b/queue-6.5/gfs2-ignore-negated-quota-changes.patch @@ -0,0 +1,91 @@ +From feae192cb79ff215edf1e9f6349eab6b23f70c7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:46:43 -0500 +Subject: gfs2: ignore negated quota changes + +From: Bob Peterson + +[ Upstream commit 4c6a08125f2249531ec01783a5f4317d7342add5 ] + +When lots of quota changes are made, there may be cases in which an +inode's quota information is increased and then decreased, such as when +blocks are added to a file, then deleted from it. If the timing is +right, function do_qc can add pending quota changes to a transaction, +then later, another call to do_qc can negate those changes, resulting +in a net gain of 0. The quota_change information is recorded in the qc +buffer (and qd element of the inode as well). The buffer is added to the +transaction by the first call to do_qc, but a subsequent call changes +the value from non-zero back to zero. At that point it's too late to +remove the buffer_head from the transaction. Later, when the quota sync +code is called, the zero-change qd element is discovered and flagged as +an assert warning. If the fs is mounted with errors=panic, the kernel +will panic. + +This is usually seen when files are truncated and the quota changes are +negated by punch_hole/truncate which uses gfs2_quota_hold and +gfs2_quota_unhold rather than block allocations that use gfs2_quota_lock +and gfs2_quota_unlock which automatically do quota sync. + +This patch solves the problem by adding a check to qd_check_sync such +that net-zero quota changes already added to the transaction are no +longer deemed necessary to be synced, and skipped. + +In this case references are taken for the qd and the slot from do_qc +so those need to be put. The normal sequence of events for a normal +non-zero quota change is as follows: + +gfs2_quota_change + do_qc + qd_hold + slot_hold + +Later, when the changes are to be synced: + +gfs2_quota_sync + qd_fish + qd_check_sync + gets qd ref via lockref_get_not_dead + do_sync + do_qc(QC_SYNC) + qd_put + lockref_put_or_lock + qd_unlock + qd_put + lockref_put_or_lock + +In the net-zero change case, we add a check to qd_check_sync so it puts +the qd and slot references acquired in gfs2_quota_change and skip the +unneeded sync. + +Signed-off-by: Bob Peterson +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/quota.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c +index 704192b736050..ccecb79eeaf8e 100644 +--- a/fs/gfs2/quota.c ++++ b/fs/gfs2/quota.c +@@ -441,6 +441,17 @@ static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd, + (sync_gen && (qd->qd_sync_gen >= *sync_gen))) + return 0; + ++ /* ++ * If qd_change is 0 it means a pending quota change was negated. ++ * We should not sync it, but we still have a qd reference and slot ++ * reference taken by gfs2_quota_change -> do_qc that need to be put. ++ */ ++ if (!qd->qd_change && test_and_clear_bit(QDF_CHANGE, &qd->qd_flags)) { ++ slot_put(qd); ++ qd_put(qd); ++ return 0; ++ } ++ + if (!lockref_get_not_dead(&qd->qd_lockref)) + return 0; + +-- +2.42.0 + diff --git a/queue-6.5/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch b/queue-6.5/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch new file mode 100644 index 00000000000..d3d7f555b00 --- /dev/null +++ b/queue-6.5/gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch @@ -0,0 +1,59 @@ +From ff4d86b0ff8966c56867d3cb1f2c1d2ce044dff8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Oct 2023 22:06:05 +0100 +Subject: gfs2: Silence "suspicious RCU usage in gfs2_permission" warning + +From: Andreas Gruenbacher + +[ Upstream commit 074d7306a4fe22fcac0b53f699f92757ab1cee99 ] + +Commit 0abd1557e21c added rcu_dereference() for dereferencing ip->i_gl +in gfs2_permission. This now causes lockdep to complain when +gfs2_permission is called in non-RCU context: + + WARNING: suspicious RCU usage in gfs2_permission + +Switch to rcu_dereference_check() and check for the MAY_NOT_BLOCK flag +to shut up lockdep when we know that dereferencing ip->i_gl is safe. + +Fixes: 0abd1557e21c ("gfs2: fix an oops in gfs2_permission") +Reported-by: syzbot+3e5130844b0c0e2b4948@syzkaller.appspotmail.com +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/inode.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 117b4b5a03072..28c3711628805 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1860,6 +1860,7 @@ static const char *gfs2_get_link(struct dentry *dentry, + int gfs2_permission(struct mnt_idmap *idmap, struct inode *inode, + int mask) + { ++ int may_not_block = mask & MAY_NOT_BLOCK; + struct gfs2_inode *ip; + struct gfs2_holder i_gh; + struct gfs2_glock *gl; +@@ -1867,14 +1868,14 @@ int gfs2_permission(struct mnt_idmap *idmap, struct inode *inode, + + gfs2_holder_mark_uninitialized(&i_gh); + ip = GFS2_I(inode); +- gl = rcu_dereference(ip->i_gl); ++ gl = rcu_dereference_check(ip->i_gl, !may_not_block); + if (unlikely(!gl)) { + /* inode is getting torn down, must be RCU mode */ +- WARN_ON_ONCE(!(mask & MAY_NOT_BLOCK)); ++ WARN_ON_ONCE(!may_not_block); + return -ECHILD; + } + if (gfs2_glock_is_locked_by_me(gl) == NULL) { +- if (mask & MAY_NOT_BLOCK) ++ if (may_not_block) + return -ECHILD; + error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) +-- +2.42.0 + diff --git a/queue-6.5/gpiolib-acpi-add-a-ignore-interrupt-quirk-for-peaq-c.patch b/queue-6.5/gpiolib-acpi-add-a-ignore-interrupt-quirk-for-peaq-c.patch new file mode 100644 index 00000000000..99aec1adb38 --- /dev/null +++ b/queue-6.5/gpiolib-acpi-add-a-ignore-interrupt-quirk-for-peaq-c.patch @@ -0,0 +1,72 @@ +From 7b85a357f506f7b73e2665fd31e403963e3e93fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 9 Sep 2023 16:18:10 +0200 +Subject: gpiolib: acpi: Add a ignore interrupt quirk for Peaq C1010 + +From: Hans de Goede + +[ Upstream commit 6cc64f6173751d212c9833bde39e856b4f585a3e ] + +On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to +a "dolby" button. At the ACPI level an _AEI event-handler +is connected which sets an ACPI variable to 1 on both +edges. This variable can be polled + cleared to 0 using WMI. + +Since the variable is set on both edges the WMI interface is pretty +useless even when polling. So instead of writing a custom WMI +driver for this the x86-android-tablets code instantiates +a gpio-keys platform device for the "dolby" button. + +Add an ignore_interrupt quirk for INT33FC:00 pin 3 on the Peaq C1010, +so that it is not seen as busy when the gpio-keys driver requests it. + +Note this replaces a hack in x86-android-tablets where it would +call acpi_gpiochip_free_interrupts() on the INT33FC:00 GPIO +controller. acpi_gpiochip_free_interrupts() is considered private +(internal) gpiolib API so x86-android-tablets should stop using it. + +Signed-off-by: Hans de Goede +Reviewed-by: Andy Shevchenko +Reviewed-by: Mika Westerberg +Acked-by: Linus Walleij +Acked-by: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20230909141816.58358-3-hdegoede@redhat.com +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib-acpi.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index a775d2bdac94f..980ec04892173 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -1655,6 +1655,26 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { + .ignore_wake = "SYNA1202:00@16", + }, + }, ++ { ++ /* ++ * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to ++ * a "dolby" button. At the ACPI level an _AEI event-handler ++ * is connected which sets an ACPI variable to 1 on both ++ * edges. This variable can be polled + cleared to 0 using ++ * WMI. But since the variable is set on both edges the WMI ++ * interface is pretty useless even when polling. ++ * So instead the x86-android-tablets code instantiates ++ * a gpio-keys platform device for it. ++ * Ignore the _AEI handler for the pin, so that it is not busy. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"), ++ }, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .ignore_interrupt = "INT33FC:00@3", ++ }, ++ }, + {} /* Terminating entry */ + }; + +-- +2.42.0 + diff --git a/queue-6.5/gpiolib-of-add-quirk-for-mt2701-cs42448-asoc-sound.patch b/queue-6.5/gpiolib-of-add-quirk-for-mt2701-cs42448-asoc-sound.patch new file mode 100644 index 00000000000..92205f9d7fe --- /dev/null +++ b/queue-6.5/gpiolib-of-add-quirk-for-mt2701-cs42448-asoc-sound.patch @@ -0,0 +1,41 @@ +From 777413ed7e5d9f9ed4f282b951cd09e5c26d61ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 15:46:24 +0200 +Subject: gpiolib: of: Add quirk for mt2701-cs42448 ASoC sound + +From: Linus Walleij + +[ Upstream commit 9e189e80dcb68528dea9e061d9704993f98cb84f ] + +These gpio names are due to old DT bindings not following the +"-gpio"/"-gpios" conventions. Handle it using a quirk so the +driver can just look up the GPIOs. + +Signed-off-by: Linus Walleij +Acked-by: Bartosz Golaszewski +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20231006-descriptors-asoc-mediatek-v1-1-07fe79f337f5@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib-of.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c +index 1436cdb5fa268..219bf8a82d8f9 100644 +--- a/drivers/gpio/gpiolib-of.c ++++ b/drivers/gpio/gpiolib-of.c +@@ -496,6 +496,10 @@ static struct gpio_desc *of_find_gpio_rename(struct device_node *np, + #if IS_ENABLED(CONFIG_SND_SOC_CS42L56) + { "reset", "cirrus,gpio-nreset", "cirrus,cs42l56" }, + #endif ++#if IS_ENABLED(CONFIG_SND_SOC_MT2701_CS42448) ++ { "i2s1-in-sel-gpio1", NULL, "mediatek,mt2701-cs42448-machine" }, ++ { "i2s1-in-sel-gpio2", NULL, "mediatek,mt2701-cs42448-machine" }, ++#endif + #if IS_ENABLED(CONFIG_SND_SOC_TLV320AIC3X) + { "reset", "gpio-reset", "ti,tlv320aic3x" }, + { "reset", "gpio-reset", "ti,tlv320aic33" }, +-- +2.42.0 + diff --git a/queue-6.5/gve-fixes-for-napi_poll-when-budget-is-0.patch b/queue-6.5/gve-fixes-for-napi_poll-when-budget-is-0.patch new file mode 100644 index 00000000000..05520fb136f --- /dev/null +++ b/queue-6.5/gve-fixes-for-napi_poll-when-budget-is-0.patch @@ -0,0 +1,89 @@ +From 0ffab897fecefc37c9fb9f35294ea70cdae4918d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 16:41:44 -0800 +Subject: gve: Fixes for napi_poll when budget is 0 + +From: Ziwei Xiao + +[ Upstream commit 278a370c1766060d2144d6cf0b06c101e1043b6d ] + +Netpoll will explicilty pass the polling call with a budget of 0 to +indicate it's clearing the Tx path only. For the gve_rx_poll and +gve_xdp_poll, they were mistakenly taking the 0 budget as the indication +to do all the work. Add check to avoid the rx path and xdp path being +called when budget is 0. And also avoid napi_complete_done being called +when budget is 0 for netpoll. + +Fixes: f5cedc84a30d ("gve: Add transmit and receive support") +Signed-off-by: Ziwei Xiao +Link: https://lore.kernel.org/r/20231114004144.2022268-1-ziweixiao@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/google/gve/gve_main.c | 8 +++++++- + drivers/net/ethernet/google/gve/gve_rx.c | 4 ---- + drivers/net/ethernet/google/gve/gve_tx.c | 4 ---- + 3 files changed, 7 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 465a6db5a40a8..79bfa2837a0e6 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -255,10 +255,13 @@ static int gve_napi_poll(struct napi_struct *napi, int budget) + if (block->tx) { + if (block->tx->q_num < priv->tx_cfg.num_queues) + reschedule |= gve_tx_poll(block, budget); +- else ++ else if (budget) + reschedule |= gve_xdp_poll(block, budget); + } + ++ if (!budget) ++ return 0; ++ + if (block->rx) { + work_done = gve_rx_poll(block, budget); + reschedule |= work_done == budget; +@@ -299,6 +302,9 @@ static int gve_napi_poll_dqo(struct napi_struct *napi, int budget) + if (block->tx) + reschedule |= gve_tx_poll_dqo(block, /*do_clean=*/true); + ++ if (!budget) ++ return 0; ++ + if (block->rx) { + work_done = gve_rx_poll_dqo(block, budget); + reschedule |= work_done == budget; +diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c +index e84a066aa1a40..73655347902d2 100644 +--- a/drivers/net/ethernet/google/gve/gve_rx.c ++++ b/drivers/net/ethernet/google/gve/gve_rx.c +@@ -1007,10 +1007,6 @@ int gve_rx_poll(struct gve_notify_block *block, int budget) + + feat = block->napi.dev->features; + +- /* If budget is 0, do all the work */ +- if (budget == 0) +- budget = INT_MAX; +- + if (budget > 0) + work_done = gve_clean_rx_done(rx, budget, feat); + +diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c +index 6957a865cff37..9f6ffc4a54f0b 100644 +--- a/drivers/net/ethernet/google/gve/gve_tx.c ++++ b/drivers/net/ethernet/google/gve/gve_tx.c +@@ -925,10 +925,6 @@ bool gve_xdp_poll(struct gve_notify_block *block, int budget) + bool repoll; + u32 to_do; + +- /* If budget is 0, do all the work */ +- if (budget == 0) +- budget = INT_MAX; +- + /* Find out how much work there is to be done */ + nic_done = gve_tx_load_event_counter(priv, tx); + to_do = min_t(u32, (nic_done - tx->done), budget); +-- +2.42.0 + diff --git a/queue-6.5/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch b/queue-6.5/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch new file mode 100644 index 00000000000..faeaed18096 --- /dev/null +++ b/queue-6.5/hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch @@ -0,0 +1,47 @@ +From dae1cd3a1ec131d325775f12a4a0f49618b585b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 15:32:09 +0200 +Subject: HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W + +From: Jiri Kosina + +[ Upstream commit 62cc9c3cb3ec1bf31cc116146185ed97b450836a ] + +This device needs ALWAYS_POLL quirk, otherwise it keeps reconnecting +indefinitely. + +Reported-by: Robert Ayrapetyan +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-quirks.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index cc0d0186a0d95..fafc40ecfd200 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -366,6 +366,7 @@ + + #define USB_VENDOR_ID_DELL 0x413c + #define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a ++#define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W 0x4503 + + #define USB_VENDOR_ID_DELORME 0x1163 + #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 3983b4f282f8f..5a48fcaa32f00 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -66,6 +66,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT }, +-- +2.42.0 + diff --git a/queue-6.5/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch b/queue-6.5/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch new file mode 100644 index 00000000000..817f017ae39 --- /dev/null +++ b/queue-6.5/hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch @@ -0,0 +1,127 @@ +From fb11272938a23e9b503bcdba49f282a797a306d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 01:58:30 +0300 +Subject: HID: lenovo: Detect quirk-free fw on cptkbd and stop applying + workaround + +From: Mikhail Khvainitski + +[ Upstream commit 46a0a2c96f0f47628190f122c2e3d879e590bcbe ] + +Built-in firmware of cptkbd handles scrolling by itself (when middle +button is pressed) but with issues: it does not support horizontal and +hi-res scrolling and upon middle button release it sends middle button +click even if there was a scrolling event. Commit 3cb5ff0220e3 ("HID: +lenovo: Hide middle-button press until release") workarounds last +issue but it's impossible to workaround scrolling-related issues +without firmware modification. + +Likely, Dennis Schneider has reverse engineered the firmware and +provided an instruction on how to patch it [1]. However, +aforementioned workaround prevents userspace (libinput) from knowing +exact moment when middle button has been pressed down and performing +"On-Button scrolling". This commit detects correctly-behaving patched +firmware if cursor movement events has been received during middle +button being pressed and stops applying workaround for this device. + +Link: https://hohlerde.org/rauch/en/elektronik/projekte/tpkbd-fix/ [1] + +Signed-off-by: Mikhail Khvainitski +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-lenovo.c | 68 ++++++++++++++++++++++++++-------------- + 1 file changed, 45 insertions(+), 23 deletions(-) + +diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c +index 44763c0da4441..9c1181313e44d 100644 +--- a/drivers/hid/hid-lenovo.c ++++ b/drivers/hid/hid-lenovo.c +@@ -51,7 +51,12 @@ struct lenovo_drvdata { + int select_right; + int sensitivity; + int press_speed; +- u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ ++ /* 0: Up ++ * 1: Down (undecided) ++ * 2: Scrolling ++ * 3: Patched firmware, disable workaround ++ */ ++ u8 middlebutton_state; + bool fn_lock; + }; + +@@ -668,31 +673,48 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, + { + struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); + +- /* "wheel" scroll events */ +- if (usage->type == EV_REL && (usage->code == REL_WHEEL || +- usage->code == REL_HWHEEL)) { +- /* Scroll events disable middle-click event */ +- cptkbd_data->middlebutton_state = 2; +- return 0; +- } ++ if (cptkbd_data->middlebutton_state != 3) { ++ /* REL_X and REL_Y events during middle button pressed ++ * are only possible on patched, bug-free firmware ++ * so set middlebutton_state to 3 ++ * to never apply workaround anymore ++ */ ++ if (cptkbd_data->middlebutton_state == 1 && ++ usage->type == EV_REL && ++ (usage->code == REL_X || usage->code == REL_Y)) { ++ cptkbd_data->middlebutton_state = 3; ++ /* send middle button press which was hold before */ ++ input_event(field->hidinput->input, ++ EV_KEY, BTN_MIDDLE, 1); ++ input_sync(field->hidinput->input); ++ } + +- /* Middle click events */ +- if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { +- if (value == 1) { +- cptkbd_data->middlebutton_state = 1; +- } else if (value == 0) { +- if (cptkbd_data->middlebutton_state == 1) { +- /* No scrolling inbetween, send middle-click */ +- input_event(field->hidinput->input, +- EV_KEY, BTN_MIDDLE, 1); +- input_sync(field->hidinput->input); +- input_event(field->hidinput->input, +- EV_KEY, BTN_MIDDLE, 0); +- input_sync(field->hidinput->input); ++ /* "wheel" scroll events */ ++ if (usage->type == EV_REL && (usage->code == REL_WHEEL || ++ usage->code == REL_HWHEEL)) { ++ /* Scroll events disable middle-click event */ ++ cptkbd_data->middlebutton_state = 2; ++ return 0; ++ } ++ ++ /* Middle click events */ ++ if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { ++ if (value == 1) { ++ cptkbd_data->middlebutton_state = 1; ++ } else if (value == 0) { ++ if (cptkbd_data->middlebutton_state == 1) { ++ /* No scrolling inbetween, send middle-click */ ++ input_event(field->hidinput->input, ++ EV_KEY, BTN_MIDDLE, 1); ++ input_sync(field->hidinput->input); ++ input_event(field->hidinput->input, ++ EV_KEY, BTN_MIDDLE, 0); ++ input_sync(field->hidinput->input); ++ } ++ cptkbd_data->middlebutton_state = 0; + } +- cptkbd_data->middlebutton_state = 0; ++ return 1; + } +- return 1; + } + + if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { +-- +2.42.0 + diff --git a/queue-6.5/i2c-dev-copy-userspace-array-safely.patch b/queue-6.5/i2c-dev-copy-userspace-array-safely.patch new file mode 100644 index 00000000000..8c8dbefa1df --- /dev/null +++ b/queue-6.5/i2c-dev-copy-userspace-array-safely.patch @@ -0,0 +1,40 @@ +From 43ecd4dc4e823cde3ccf4b1c485e7e675b02ea3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Nov 2023 20:26:13 +0100 +Subject: i2c: dev: copy userspace array safely + +From: Philipp Stanner + +[ Upstream commit cc9c54232f04aef3a5d7f64a0ece7df00f1aaa3d ] + +i2c-dev.c utilizes memdup_user() to copy a userspace array. This is done +without an overflow check. + +Use the new wrapper memdup_array_user() to copy the array more safely. + +Suggested-by: Dave Airlie +Signed-off-by: Philipp Stanner +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/i2c-dev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c +index a01b59e3599b5..7d337380a05d9 100644 +--- a/drivers/i2c/i2c-dev.c ++++ b/drivers/i2c/i2c-dev.c +@@ -450,8 +450,8 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) + return -EINVAL; + +- rdwr_pa = memdup_user(rdwr_arg.msgs, +- rdwr_arg.nmsgs * sizeof(struct i2c_msg)); ++ rdwr_pa = memdup_array_user(rdwr_arg.msgs, ++ rdwr_arg.nmsgs, sizeof(struct i2c_msg)); + if (IS_ERR(rdwr_pa)) + return PTR_ERR(rdwr_pa); + +-- +2.42.0 + diff --git a/queue-6.5/i2c-fix-memleak-in-i2c_new_client_device.patch b/queue-6.5/i2c-fix-memleak-in-i2c_new_client_device.patch new file mode 100644 index 00000000000..4c90b330938 --- /dev/null +++ b/queue-6.5/i2c-fix-memleak-in-i2c_new_client_device.patch @@ -0,0 +1,99 @@ +From 63df1142ed19901e70f60a57f7524b513ca5b973 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 11:19:52 +0200 +Subject: i2c: fix memleak in i2c_new_client_device() + +From: Wolfram Sang + +[ Upstream commit 6af79f7fe748fe6a3c5c3a63d7f35981a82c2769 ] + +Yang Yingliang reported a memleak: +=== + +I got memory leak as follows when doing fault injection test: + +unreferenced object 0xffff888014aec078 (size 8): + comm "xrun", pid 356, jiffies 4294910619 (age 16.332s) + hex dump (first 8 bytes): + 31 2d 30 30 31 63 00 00 1-001c.. + backtrace: + [<00000000eb56c0a9>] __kmalloc_track_caller+0x1a6/0x300 + [<000000000b220ea3>] kvasprintf+0xad/0x140 + [<00000000b83203e5>] kvasprintf_const+0x62/0x190 + [<000000002a5eab37>] kobject_set_name_vargs+0x56/0x140 + [<00000000300ac279>] dev_set_name+0xb0/0xe0 + [<00000000b66ebd6f>] i2c_new_client_device+0x7e4/0x9a0 + +If device_register() returns error in i2c_new_client_device(), +the name allocated by i2c_dev_set_name() need be freed. As +comment of device_register() says, it should use put_device() +to give up the reference in the error path. + +=== +I think this solution is less intrusive and more robust than he +originally proposed solutions, though. + +Reported-by: Yang Yingliang +Closes: http://patchwork.ozlabs.org/project/linux-i2c/patch/20221124085448.3620240-1-yangyingliang@huawei.com/ +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/i2c-core-base.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c +index 60746652fd525..7f30bcceebaed 100644 +--- a/drivers/i2c/i2c-core-base.c ++++ b/drivers/i2c/i2c-core-base.c +@@ -931,8 +931,9 @@ int i2c_dev_irq_from_resources(const struct resource *resources, + struct i2c_client * + i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info) + { +- struct i2c_client *client; +- int status; ++ struct i2c_client *client; ++ bool need_put = false; ++ int status; + + client = kzalloc(sizeof *client, GFP_KERNEL); + if (!client) +@@ -970,7 +971,6 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf + client->dev.fwnode = info->fwnode; + + device_enable_async_suspend(&client->dev); +- i2c_dev_set_name(adap, client, info); + + if (info->swnode) { + status = device_add_software_node(&client->dev, info->swnode); +@@ -982,6 +982,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf + } + } + ++ i2c_dev_set_name(adap, client, info); + status = device_register(&client->dev); + if (status) + goto out_remove_swnode; +@@ -993,6 +994,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf + + out_remove_swnode: + device_remove_software_node(&client->dev); ++ need_put = true; + out_err_put_of_node: + of_node_put(info->of_node); + out_err: +@@ -1000,7 +1002,10 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf + "Failed to register i2c client %s at 0x%02x (%d)\n", + client->name, client->addr, status); + out_err_silent: +- kfree(client); ++ if (need_put) ++ put_device(&client->dev); ++ else ++ kfree(client); + return ERR_PTR(status); + } + EXPORT_SYMBOL_GPL(i2c_new_client_device); +-- +2.42.0 + diff --git a/queue-6.5/i2c-i801-add-support-for-intel-birch-stream-soc.patch b/queue-6.5/i2c-i801-add-support-for-intel-birch-stream-soc.patch new file mode 100644 index 00000000000..775dcc885c8 --- /dev/null +++ b/queue-6.5/i2c-i801-add-support-for-intel-birch-stream-soc.patch @@ -0,0 +1,77 @@ +From 4d4ac6c41a6fe4f61061232bc005344388cb23e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 11:28:04 +0300 +Subject: i2c: i801: Add support for Intel Birch Stream SoC + +From: Jarkko Nikula + +[ Upstream commit 8c56f9ef25a33e51f09a448d25cf863b61c9658d ] + +Add SMBus PCI ID on Intel Birch Stream SoC. + +Signed-off-by: Jarkko Nikula +Reviewed-by: Andi Shyti +Reviewed-by: Jean Delvare +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + Documentation/i2c/busses/i2c-i801.rst | 1 + + drivers/i2c/busses/Kconfig | 1 + + drivers/i2c/busses/i2c-i801.c | 3 +++ + 3 files changed, 5 insertions(+) + +diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst +index e76e68ccf7182..10eced6c2e462 100644 +--- a/Documentation/i2c/busses/i2c-i801.rst ++++ b/Documentation/i2c/busses/i2c-i801.rst +@@ -47,6 +47,7 @@ Supported adapters: + * Intel Alder Lake (PCH) + * Intel Raptor Lake (PCH) + * Intel Meteor Lake (SOC and PCH) ++ * Intel Birch Stream (SOC) + + Datasheets: Publicly available at the Intel website + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 9cfe8fc509d7d..c91d4ea35c9b8 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -158,6 +158,7 @@ config I2C_I801 + Alder Lake (PCH) + Raptor Lake (PCH) + Meteor Lake (SOC and PCH) ++ Birch Stream (SOC) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 2a3215ac01b3a..db4d73456f255 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -79,6 +79,7 @@ + * Meteor Lake-P (SOC) 0x7e22 32 hard yes yes yes + * Meteor Lake SoC-S (SOC) 0xae22 32 hard yes yes yes + * Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes ++ * Birch Stream (SOC) 0x5796 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no +@@ -231,6 +232,7 @@ + #define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3 ++#define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS 0x5796 + #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 + #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 +@@ -1044,6 +1046,7 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +-- +2.42.0 + diff --git a/queue-6.5/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch b/queue-6.5/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch new file mode 100644 index 00000000000..a48cd9ebd18 --- /dev/null +++ b/queue-6.5/i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch @@ -0,0 +1,39 @@ +From fbdaebdb55c239b653e2f25843adac0a674c1224 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Apr 2016 08:54:30 +0800 +Subject: i2c: sun6i-p2wi: Prevent potential division by zero + +From: Axel Lin + +[ Upstream commit 5ac61d26b8baff5b2e5a9f3dc1ef63297e4b53e7 ] + +Make sure we don't OOPS in case clock-frequency is set to 0 in a DT. The +variable set here is later used as a divisor. + +Signed-off-by: Axel Lin +Acked-by: Boris Brezillon +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-sun6i-p2wi.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c +index fa6020dced595..85e035e7a1d75 100644 +--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c ++++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c +@@ -201,6 +201,11 @@ static int p2wi_probe(struct platform_device *pdev) + return -EINVAL; + } + ++ if (clk_freq == 0) { ++ dev_err(dev, "clock-frequency is set to 0 in DT\n"); ++ return -EINVAL; ++ } ++ + if (of_get_child_count(np) > 1) { + dev_err(dev, "P2WI only supports one slave device\n"); + return -EINVAL; +-- +2.42.0 + diff --git a/queue-6.5/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch b/queue-6.5/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch new file mode 100644 index 00000000000..8784eb30eaa --- /dev/null +++ b/queue-6.5/i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch @@ -0,0 +1,82 @@ +From 85359fb884786e3ff44527d03a8fd82250b31f61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 16:02:37 +0800 +Subject: i3c: master: mipi-i3c-hci: Fix a kernel panic for accessing DAT_data. + +From: Billy Tsai + +[ Upstream commit b53e9758a31c683fc8615df930262192ed5f034b ] + +The `i3c_master_bus_init` function may attach the I2C devices before the +I3C bus initialization. In this flow, the DAT `alloc_entry`` will be used +before the DAT `init`. Additionally, if the `i3c_master_bus_init` fails, +the DAT `cleanup` will execute before the device is detached, which will +execue DAT `free_entry` function. The above scenario can cause the driver +to use DAT_data when it is NULL. + +Signed-off-by: Billy Tsai +Link: https://lore.kernel.org/r/20231023080237.560936-1-billy_tsai@aspeedtech.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/mipi-i3c-hci/dat_v1.c | 29 ++++++++++++++++-------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c +index 97bb49ff5b53b..47b9b4d4ed3fc 100644 +--- a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c ++++ b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c +@@ -64,15 +64,17 @@ static int hci_dat_v1_init(struct i3c_hci *hci) + return -EOPNOTSUPP; + } + +- /* use a bitmap for faster free slot search */ +- hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL); +- if (!hci->DAT_data) +- return -ENOMEM; +- +- /* clear them */ +- for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) { +- dat_w0_write(dat_idx, 0); +- dat_w1_write(dat_idx, 0); ++ if (!hci->DAT_data) { ++ /* use a bitmap for faster free slot search */ ++ hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL); ++ if (!hci->DAT_data) ++ return -ENOMEM; ++ ++ /* clear them */ ++ for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) { ++ dat_w0_write(dat_idx, 0); ++ dat_w1_write(dat_idx, 0); ++ } + } + + return 0; +@@ -87,7 +89,13 @@ static void hci_dat_v1_cleanup(struct i3c_hci *hci) + static int hci_dat_v1_alloc_entry(struct i3c_hci *hci) + { + unsigned int dat_idx; ++ int ret; + ++ if (!hci->DAT_data) { ++ ret = hci_dat_v1_init(hci); ++ if (ret) ++ return ret; ++ } + dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries); + if (dat_idx >= hci->DAT_entries) + return -ENOENT; +@@ -103,7 +111,8 @@ static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx) + { + dat_w0_write(dat_idx, 0); + dat_w1_write(dat_idx, 0); +- __clear_bit(dat_idx, hci->DAT_data); ++ if (hci->DAT_data) ++ __clear_bit(dat_idx, hci->DAT_data); + } + + static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci, +-- +2.42.0 + diff --git a/queue-6.5/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch b/queue-6.5/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch new file mode 100644 index 00000000000..cea7c1485a2 --- /dev/null +++ b/queue-6.5/i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch @@ -0,0 +1,38 @@ +From 1a1416cdd8665e79bf2fa61bb6411b0c5784fe2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:56:56 +0300 +Subject: i3c: mipi-i3c-hci: Fix out of bounds access in hci_dma_irq_handler + +From: Jarkko Nikula + +[ Upstream commit 45a832f989e520095429589d5b01b0c65da9b574 ] + +Do not loop over ring headers in hci_dma_irq_handler() that are not +allocated and enabled in hci_dma_init(). Otherwise out of bounds access +will occur from rings->headers[i] access when i >= number of allocated +ring headers. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20230921055704.1087277-5-jarkko.nikula@linux.intel.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/mipi-i3c-hci/dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c +index 2990ac9eaade7..71b5dbe45c45c 100644 +--- a/drivers/i3c/master/mipi-i3c-hci/dma.c ++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c +@@ -734,7 +734,7 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask) + unsigned int i; + bool handled = false; + +- for (i = 0; mask && i < 8; i++) { ++ for (i = 0; mask && i < rings->total; i++) { + struct hci_rh_data *rh; + u32 status; + +-- +2.42.0 + diff --git a/queue-6.5/iio-adc-stm32-adc-harden-against-null-pointer-deref-.patch b/queue-6.5/iio-adc-stm32-adc-harden-against-null-pointer-deref-.patch new file mode 100644 index 00000000000..d23188c496d --- /dev/null +++ b/queue-6.5/iio-adc-stm32-adc-harden-against-null-pointer-deref-.patch @@ -0,0 +1,53 @@ +From 93ba6452522c69e14818be5a181c16427b66da85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Jul 2023 23:55:50 +0800 +Subject: iio: adc: stm32-adc: harden against NULL pointer deref in + stm32_adc_probe() + +From: Zhang Shurong + +[ Upstream commit 3a23b384e7e3d64d5587ad10729a34d4f761517e ] + +of_match_device() may fail and returns a NULL pointer. + +In practice there is no known reasonable way to trigger this, but +in case one is added in future, harden the code by adding the check + +Signed-off-by: Zhang Shurong +Link: https://lore.kernel.org/r/tencent_994DA85912C937E3B5405BA960B31ED90A08@qq.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/stm32-adc-core.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c +index 48f02dcc81c1b..70011fdbf5f63 100644 +--- a/drivers/iio/adc/stm32-adc-core.c ++++ b/drivers/iio/adc/stm32-adc-core.c +@@ -706,6 +706,8 @@ static int stm32_adc_probe(struct platform_device *pdev) + struct stm32_adc_priv *priv; + struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; ++ const struct of_device_id *of_id; ++ + struct resource *res; + u32 max_rate; + int ret; +@@ -718,8 +720,11 @@ static int stm32_adc_probe(struct platform_device *pdev) + return -ENOMEM; + platform_set_drvdata(pdev, &priv->common); + +- priv->cfg = (const struct stm32_adc_priv_cfg *) +- of_match_device(dev->driver->of_match_table, dev)->data; ++ of_id = of_match_device(dev->driver->of_match_table, dev); ++ if (!of_id) ++ return -ENODEV; ++ ++ priv->cfg = (const struct stm32_adc_priv_cfg *)of_id->data; + priv->nb_adc_max = priv->cfg->num_adcs; + spin_lock_init(&priv->common.lock); + +-- +2.42.0 + diff --git a/queue-6.5/io_uring-fdinfo-remove-need-for-sqpoll-lock-for-thre.patch b/queue-6.5/io_uring-fdinfo-remove-need-for-sqpoll-lock-for-thre.patch new file mode 100644 index 00000000000..8460c387e6a --- /dev/null +++ b/queue-6.5/io_uring-fdinfo-remove-need-for-sqpoll-lock-for-thre.patch @@ -0,0 +1,104 @@ +From a5fa4787f337a9cd3ad767db0c024f339f6f8ac1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 09:55:50 -0700 +Subject: io_uring/fdinfo: remove need for sqpoll lock for thread/pid retrieval + +From: Jens Axboe + +[ Upstream commit a0d45c3f596be53c1bd8822a1984532d14fdcea9 ] + +A previous commit added a trylock for getting the SQPOLL thread info via +fdinfo, but this introduced a regression where we often fail to get it if +the thread is busy. For that case, we end up not printing the current CPU +and PID info. + +Rather than rely on this lock, just print the pid we already stored in +the io_sq_data struct, and ensure we update the current CPU every time +we've slept or potentially rescheduled. The latter won't potentially be +100% accurate, but that wasn't the case before either as the task can +get migrated at any time unless it has been pinned at creation time. + +We retain keeping the io_sq_data dereference inside the ctx->uring_lock, +as it has always been, as destruction of the thread and data happen below +that. We could make this RCU safe, but there's little point in doing that. + +With this, we always print the last valid information we had, rather than +have spurious outputs with missing information. + +Fixes: 7644b1a1c9a7 ("io_uring/fdinfo: lock SQ thread while retrieving thread cpu/pid") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/fdinfo.c | 9 ++------- + io_uring/sqpoll.c | 12 ++++++++++-- + 2 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c +index b603a06f7103d..5fcfe03ed93ec 100644 +--- a/io_uring/fdinfo.c ++++ b/io_uring/fdinfo.c +@@ -139,13 +139,8 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, + if (has_lock && (ctx->flags & IORING_SETUP_SQPOLL)) { + struct io_sq_data *sq = ctx->sq_data; + +- if (mutex_trylock(&sq->lock)) { +- if (sq->thread) { +- sq_pid = task_pid_nr(sq->thread); +- sq_cpu = task_cpu(sq->thread); +- } +- mutex_unlock(&sq->lock); +- } ++ sq_pid = sq->task_pid; ++ sq_cpu = sq->sq_cpu; + } + + seq_printf(m, "SqThread:\t%d\n", sq_pid); +diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c +index bd6c2c7959a5b..65b5dbe3c850e 100644 +--- a/io_uring/sqpoll.c ++++ b/io_uring/sqpoll.c +@@ -214,6 +214,7 @@ static bool io_sqd_handle_event(struct io_sq_data *sqd) + did_sig = get_signal(&ksig); + cond_resched(); + mutex_lock(&sqd->lock); ++ sqd->sq_cpu = raw_smp_processor_id(); + } + return did_sig || test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state); + } +@@ -229,10 +230,15 @@ static int io_sq_thread(void *data) + snprintf(buf, sizeof(buf), "iou-sqp-%d", sqd->task_pid); + set_task_comm(current, buf); + +- if (sqd->sq_cpu != -1) ++ /* reset to our pid after we've set task_comm, for fdinfo */ ++ sqd->task_pid = current->pid; ++ ++ if (sqd->sq_cpu != -1) { + set_cpus_allowed_ptr(current, cpumask_of(sqd->sq_cpu)); +- else ++ } else { + set_cpus_allowed_ptr(current, cpu_online_mask); ++ sqd->sq_cpu = raw_smp_processor_id(); ++ } + + mutex_lock(&sqd->lock); + while (1) { +@@ -261,6 +267,7 @@ static int io_sq_thread(void *data) + mutex_unlock(&sqd->lock); + cond_resched(); + mutex_lock(&sqd->lock); ++ sqd->sq_cpu = raw_smp_processor_id(); + } + continue; + } +@@ -294,6 +301,7 @@ static int io_sq_thread(void *data) + mutex_unlock(&sqd->lock); + schedule(); + mutex_lock(&sqd->lock); ++ sqd->sq_cpu = raw_smp_processor_id(); + } + list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) + atomic_andnot(IORING_SQ_NEED_WAKEUP, +-- +2.42.0 + diff --git a/queue-6.5/ipvlan-add-ipvlan_route_v6_outbound-helper.patch b/queue-6.5/ipvlan-add-ipvlan_route_v6_outbound-helper.patch new file mode 100644 index 00000000000..58de488552f --- /dev/null +++ b/queue-6.5/ipvlan-add-ipvlan_route_v6_outbound-helper.patch @@ -0,0 +1,272 @@ +From 5c6ac47483d11b83622921a8d3fb59aae2e42def Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 15:22:41 +0000 +Subject: ipvlan: add ipvlan_route_v6_outbound() helper + +From: Eric Dumazet + +[ Upstream commit 18f039428c7df183b09c69ebf10ffd4e521035d2 ] + +Inspired by syzbot reports using a stack of multiple ipvlan devices. + +Reduce stack size needed in ipvlan_process_v6_outbound() by moving +the flowi6 struct used for the route lookup in an non inlined +helper. ipvlan_route_v6_outbound() needs 120 bytes on the stack, +immediately reclaimed. + +Also make sure ipvlan_process_v4_outbound() is not inlined. + +We might also have to lower MAX_NEST_DEV, because only syzbot uses +setups with more than four stacked devices. + +BUG: TASK stack guard page was hit at ffffc9000e803ff8 (stack is ffffc9000e804000..ffffc9000e808000) +stack guard page: 0000 [#1] SMP KASAN +CPU: 0 PID: 13442 Comm: syz-executor.4 Not tainted 6.1.52-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023 +RIP: 0010:kasan_check_range+0x4/0x2a0 mm/kasan/generic.c:188 +Code: 48 01 c6 48 89 c7 e8 db 4e c1 03 31 c0 5d c3 cc 0f 0b eb 02 0f 0b b8 ea ff ff ff 5d c3 cc 00 00 cc cc 00 00 cc cc 55 48 89 e5 <41> 57 41 56 41 55 41 54 53 b0 01 48 85 f6 0f 84 a4 01 00 00 48 89 +RSP: 0018:ffffc9000e804000 EFLAGS: 00010246 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff817e5bf2 +RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffff887c6568 +RBP: ffffc9000e804000 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: dffffc0000000001 R12: 1ffff92001d0080c +R13: dffffc0000000000 R14: ffffffff87e6b100 R15: 0000000000000000 +FS: 00007fd0c55826c0(0000) GS:ffff8881f6800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: ffffc9000e803ff8 CR3: 0000000170ef7000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: +<#DF> + + +[] __kasan_check_read+0x11/0x20 mm/kasan/shadow.c:31 +[] instrument_atomic_read include/linux/instrumented.h:72 [inline] +[] _test_bit include/asm-generic/bitops/instrumented-non-atomic.h:141 [inline] +[] cpumask_test_cpu include/linux/cpumask.h:506 [inline] +[] cpu_online include/linux/cpumask.h:1092 [inline] +[] trace_lock_acquire include/trace/events/lock.h:24 [inline] +[] lock_acquire+0xe2/0x590 kernel/locking/lockdep.c:5632 +[] rcu_lock_acquire+0x2e/0x40 include/linux/rcupdate.h:306 +[] rcu_read_lock include/linux/rcupdate.h:747 [inline] +[] ip6_pol_route+0x15d/0x1440 net/ipv6/route.c:2221 +[] ip6_pol_route_output+0x50/0x80 net/ipv6/route.c:2606 +[] pol_lookup_func include/net/ip6_fib.h:584 [inline] +[] fib6_rule_lookup+0x265/0x620 net/ipv6/fib6_rules.c:116 +[] ip6_route_output_flags_noref+0x2d9/0x3a0 net/ipv6/route.c:2638 +[] ip6_route_output_flags+0xca/0x340 net/ipv6/route.c:2651 +[] ip6_route_output include/net/ip6_route.h:100 [inline] +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:473 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0xc33/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_hh_output include/net/neighbour.h:529 [inline] +[] neigh_output include/net/neighbour.h:543 [inline] +[] ip6_finish_output2+0x160d/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161 +[] ipvlan_process_v6_outbound drivers/net/ipvlan/ipvlan_core.c:483 [inline] +[] ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:529 [inline] +[] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +[] ipvlan_queue_xmit+0x1174/0x1be0 drivers/net/ipvlan/ipvlan_core.c:677 +[] ipvlan_start_xmit+0x49/0x100 drivers/net/ipvlan/ipvlan_main.c:229 +[] netdev_start_xmit include/linux/netdevice.h:4966 [inline] +[] xmit_one net/core/dev.c:3644 [inline] +[] dev_hard_start_xmit+0x320/0x980 net/core/dev.c:3660 +[] __dev_queue_xmit+0x16b2/0x3370 net/core/dev.c:4324 +[] dev_queue_xmit include/linux/netdevice.h:3067 [inline] +[] neigh_resolve_output+0x64e/0x750 net/core/neighbour.c:1560 +[] neigh_output include/net/neighbour.h:545 [inline] +[] ip6_finish_output2+0x1643/0x1ae0 net/ipv6/ip6_output.c:139 +[] __ip6_finish_output net/ipv6/ip6_output.c:200 [inline] +[] ip6_finish_output+0x6c6/0xb10 net/ipv6/ip6_output.c:211 +[] NF_HOOK_COND include/linux/netfilter.h:298 [inline] +[] ip6_output+0x2bc/0x3d0 net/ipv6/ip6_output.c:232 +[] dst_output include/net/dst.h:444 [inline] +[] NF_HOOK include/linux/netfilter.h:309 [inline] +[] ip6_xmit+0x11a4/0x1b20 net/ipv6/ip6_output.c:352 +[] sctp_v6_xmit+0x9ae/0x1230 net/sctp/ipv6.c:250 +[] sctp_packet_transmit+0x25de/0x2bc0 net/sctp/output.c:653 +[] sctp_packet_singleton+0x202/0x310 net/sctp/outqueue.c:783 +[] sctp_outq_flush_ctrl net/sctp/outqueue.c:914 [inline] +[] sctp_outq_flush+0x661/0x3d40 net/sctp/outqueue.c:1212 +[] sctp_outq_uncork+0x79/0xb0 net/sctp/outqueue.c:764 +[] sctp_side_effects net/sctp/sm_sideeffect.c:1199 [inline] +[] sctp_do_sm+0x55c0/0x5c30 net/sctp/sm_sideeffect.c:1170 +[] sctp_primitive_ASSOCIATE+0x97/0xc0 net/sctp/primitive.c:73 +[] sctp_sendmsg_to_asoc+0xf62/0x17b0 net/sctp/socket.c:1839 +[] sctp_sendmsg+0x212e/0x33b0 net/sctp/socket.c:2029 +[] inet_sendmsg+0x149/0x310 net/ipv4/af_inet.c:849 +[] sock_sendmsg_nosec net/socket.c:716 [inline] +[] sock_sendmsg net/socket.c:736 [inline] +[] ____sys_sendmsg+0x572/0x8c0 net/socket.c:2504 +[] ___sys_sendmsg net/socket.c:2558 [inline] +[] __sys_sendmsg+0x271/0x360 net/socket.c:2587 +[] __do_sys_sendmsg net/socket.c:2596 [inline] +[] __se_sys_sendmsg net/socket.c:2594 [inline] +[] __x64_sys_sendmsg+0x7f/0x90 net/socket.c:2594 +[] do_syscall_x64 arch/x86/entry/common.c:51 [inline] +[] do_syscall_64+0x53/0x80 arch/x86/entry/common.c:84 +[] entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Mahesh Bandewar +Cc: Willem de Bruijn +Reviewed-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ipvlan/ipvlan_core.c | 41 +++++++++++++++++++------------- + 1 file changed, 25 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index 21e9cac731218..2d5b021b4ea60 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -411,7 +411,7 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h, + return addr; + } + +-static int ipvlan_process_v4_outbound(struct sk_buff *skb) ++static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) + { + const struct iphdr *ip4h = ip_hdr(skb); + struct net_device *dev = skb->dev; +@@ -453,13 +453,11 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) + } + + #if IS_ENABLED(CONFIG_IPV6) +-static int ipvlan_process_v6_outbound(struct sk_buff *skb) ++ ++static noinline_for_stack int ++ipvlan_route_v6_outbound(struct net_device *dev, struct sk_buff *skb) + { + const struct ipv6hdr *ip6h = ipv6_hdr(skb); +- struct net_device *dev = skb->dev; +- struct net *net = dev_net(dev); +- struct dst_entry *dst; +- int err, ret = NET_XMIT_DROP; + struct flowi6 fl6 = { + .flowi6_oif = dev->ifindex, + .daddr = ip6h->daddr, +@@ -469,27 +467,38 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) + .flowi6_mark = skb->mark, + .flowi6_proto = ip6h->nexthdr, + }; ++ struct dst_entry *dst; ++ int err; + +- dst = ip6_route_output(net, NULL, &fl6); +- if (dst->error) { +- ret = dst->error; ++ dst = ip6_route_output(dev_net(dev), NULL, &fl6); ++ err = dst->error; ++ if (err) { + dst_release(dst); +- goto err; ++ return err; + } + skb_dst_set(skb, dst); ++ return 0; ++} ++ ++static int ipvlan_process_v6_outbound(struct sk_buff *skb) ++{ ++ struct net_device *dev = skb->dev; ++ int err, ret = NET_XMIT_DROP; ++ ++ err = ipvlan_route_v6_outbound(dev, skb); ++ if (unlikely(err)) { ++ DEV_STATS_INC(dev, tx_errors); ++ kfree_skb(skb); ++ return err; ++ } + + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + +- err = ip6_local_out(net, skb->sk, skb); ++ err = ip6_local_out(dev_net(dev), skb->sk, skb); + if (unlikely(net_xmit_eval(err))) + DEV_STATS_INC(dev, tx_errors); + else + ret = NET_XMIT_SUCCESS; +- goto out; +-err: +- DEV_STATS_INC(dev, tx_errors); +- kfree_skb(skb); +-out: + return ret; + } + #else +-- +2.42.0 + diff --git a/queue-6.5/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch b/queue-6.5/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch new file mode 100644 index 00000000000..86e2b1db2d8 --- /dev/null +++ b/queue-6.5/jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch @@ -0,0 +1,87 @@ +From 13c80d33e3ac0e6bcf41ad57153813c7d2160be4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 11:17:18 +0530 +Subject: jfs: fix array-index-out-of-bounds in dbFindLeaf + +From: Manas Ghandat + +[ Upstream commit 22cad8bc1d36547cdae0eef316c47d917ce3147c ] + +Currently while searching for dmtree_t for sufficient free blocks there +is an array out of bounds while getting element in tp->dm_stree. To add +the required check for out of bound we first need to determine the type +of dmtree. Thus added an extra parameter to dbFindLeaf so that the type +of tree can be determined and the required check can be applied. + +Reported-by: syzbot+aea1ad91e854d0a83e04@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=aea1ad91e854d0a83e04 +Signed-off-by: Manas Ghandat +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_dmap.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 4d59373f9e6c9..11c77757ead9e 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, + static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); + static int dbFindBits(u32 word, int l2nb); + static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); +-static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); ++static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl); + static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + int nblocks); + static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, +@@ -1717,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) + * dbFindLeaf() returns the index of the leaf at which + * free space was found. + */ +- rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx); ++ rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true); + + /* release the buffer. + */ +@@ -1964,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp, + * free space. if sufficient free space is found, dbFindLeaf() + * returns the index of the leaf at which free space was found. + */ +- if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) ++ if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false)) + return -ENOSPC; + + if (leafidx < 0) +@@ -2928,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) + * leafidx - return pointer to be set to the index of the leaf + * describing at least l2nb free blocks if sufficient + * free blocks are found. ++ * is_ctl - determines if the tree is of type ctl + * + * RETURN VALUES: + * 0 - success + * -ENOSPC - insufficient free blocks. + */ +-static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) ++static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl) + { + int ti, n = 0, k, x = 0; ++ int max_size; ++ ++ max_size = is_ctl ? CTLTREESIZE : TREESIZE; + + /* first check the root of the tree to see if there is + * sufficient free space. +@@ -2956,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) + /* sufficient free space found. move to the next + * level (or quit if this is the last level). + */ ++ if (x + n > max_size) ++ return -ENOSPC; + if (l2nb <= tp->dmt_stree[x + n]) + break; + } +-- +2.42.0 + diff --git a/queue-6.5/jfs-fix-array-index-out-of-bounds-in-dialloc.patch b/queue-6.5/jfs-fix-array-index-out-of-bounds-in-dialloc.patch new file mode 100644 index 00000000000..83acf2ee0b5 --- /dev/null +++ b/queue-6.5/jfs-fix-array-index-out-of-bounds-in-dialloc.patch @@ -0,0 +1,48 @@ +From 470994a0c621a3da76b4e2f82c485f6df161ddae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 13:10:40 +0530 +Subject: jfs: fix array-index-out-of-bounds in diAlloc + +From: Manas Ghandat + +[ Upstream commit 05d9ea1ceb62a55af6727a69269a4fd310edf483 ] + +Currently there is not check against the agno of the iag while +allocating new inodes to avoid fragmentation problem. Added the check +which is required. + +Reported-by: syzbot+79d792676d8ac050949f@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=79d792676d8ac050949f +Signed-off-by: Manas Ghandat +Signed-off-by: Dave Kleikamp +Signed-off-by: Sasha Levin +--- + fs/jfs/jfs_imap.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c +index 6fb28572cb2c6..34f1358264e23 100644 +--- a/fs/jfs/jfs_imap.c ++++ b/fs/jfs/jfs_imap.c +@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) + int diAlloc(struct inode *pip, bool dir, struct inode *ip) + { + int rc, ino, iagno, addext, extno, bitno, sword; +- int nwords, rem, i, agno; ++ int nwords, rem, i, agno, dn_numag; + u32 mask, inosmap, extsmap; + struct inode *ipimap; + struct metapage *mp; +@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) + + /* get the ag number of this iag */ + agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); ++ dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag; ++ if (agno < 0 || agno > dn_numag) ++ return -EIO; + + if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { + /* +-- +2.42.0 + diff --git a/queue-6.5/kernel-kexec-copy-user-array-safely.patch b/queue-6.5/kernel-kexec-copy-user-array-safely.patch new file mode 100644 index 00000000000..3637e599c0e --- /dev/null +++ b/queue-6.5/kernel-kexec-copy-user-array-safely.patch @@ -0,0 +1,42 @@ +From 96b7fee23a5b2f7ac14edef2da745ee63434cb96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:10 +0200 +Subject: kernel: kexec: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit 569c8d82f95eb5993c84fb61a649a9c4ddd208b3 ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Acked-by: Baoquan He +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-4-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/kexec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/kexec.c b/kernel/kexec.c +index 92d301f987766..f6067c1bb0893 100644 +--- a/kernel/kexec.c ++++ b/kernel/kexec.c +@@ -242,7 +242,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, + ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT)) + return -EINVAL; + +- ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0])); ++ ksegments = memdup_array_user(segments, nr_segments, sizeof(ksegments[0])); + if (IS_ERR(ksegments)) + return PTR_ERR(ksegments); + +-- +2.42.0 + diff --git a/queue-6.5/kernel-watch_queue-copy-user-array-safely.patch b/queue-6.5/kernel-watch_queue-copy-user-array-safely.patch new file mode 100644 index 00000000000..eb773cd1a1c --- /dev/null +++ b/queue-6.5/kernel-watch_queue-copy-user-array-safely.patch @@ -0,0 +1,41 @@ +From b222c8a9b5282ec95efd0107be100009063f893d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:11 +0200 +Subject: kernel: watch_queue: copy user-array safely + +From: Philipp Stanner + +[ Upstream commit ca0776571d3163bd03b3e8c9e3da936abfaecbf6 ] + +Currently, there is no overflow-check with memdup_user(). + +Use the new function memdup_array_user() instead of memdup_user() for +duplicating the user-space array safely. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-5-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/watch_queue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c +index d0b6b390ee423..778b4056700ff 100644 +--- a/kernel/watch_queue.c ++++ b/kernel/watch_queue.c +@@ -331,7 +331,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe, + filter.__reserved != 0) + return -EINVAL; + +- tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf)); ++ tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); + if (IS_ERR(tf)) + return PTR_ERR(tf); + +-- +2.42.0 + diff --git a/queue-6.5/kgdb-flush-console-before-entering-kgdb-on-panic.patch b/queue-6.5/kgdb-flush-console-before-entering-kgdb-on-panic.patch new file mode 100644 index 00000000000..fd2f365aa76 --- /dev/null +++ b/queue-6.5/kgdb-flush-console-before-entering-kgdb-on-panic.patch @@ -0,0 +1,59 @@ +From f7ae77bb909db973fbf3dd3350a7727feb774106 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Aug 2023 13:19:46 -0700 +Subject: kgdb: Flush console before entering kgdb on panic + +From: Douglas Anderson + +[ Upstream commit dd712d3d45807db9fcae28a522deee85c1f2fde6 ] + +When entering kdb/kgdb on a kernel panic, it was be observed that the +console isn't flushed before the `kdb` prompt came up. Specifically, +when using the buddy lockup detector on arm64 and running: + echo HARDLOCKUP > /sys/kernel/debug/provoke-crash/DIRECT + +I could see: + [ 26.161099] lkdtm: Performing direct entry HARDLOCKUP + [ 32.499881] watchdog: Watchdog detected hard LOCKUP on cpu 6 + [ 32.552865] Sending NMI from CPU 5 to CPUs 6: + [ 32.557359] NMI backtrace for cpu 6 + ... [backtrace for cpu 6] ... + [ 32.558353] NMI backtrace for cpu 5 + ... [backtrace for cpu 5] ... + [ 32.867471] Sending NMI from CPU 5 to CPUs 0-4,7: + [ 32.872321] NMI backtrace forP cpuANC: Hard LOCKUP + + Entering kdb (current=..., pid 0) on processor 5 due to Keyboard Entry + [5]kdb> + +As you can see, backtraces for the other CPUs start printing and get +interleaved with the kdb PANIC print. + +Let's replicate the commands to flush the console in the kdb panic +entry point to avoid this. + +Signed-off-by: Douglas Anderson +Link: https://lore.kernel.org/r/20230822131945.1.I5b460ae8f954e4c4f628a373d6e74713c06dd26f@changeid +Signed-off-by: Daniel Thompson +Signed-off-by: Sasha Levin +--- + kernel/debug/debug_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c +index d5e9ccde3ab8e..3a904d8697c8f 100644 +--- a/kernel/debug/debug_core.c ++++ b/kernel/debug/debug_core.c +@@ -1006,6 +1006,9 @@ void kgdb_panic(const char *msg) + if (panic_timeout) + return; + ++ debug_locks_off(); ++ console_flush_on_panic(CONSOLE_FLUSH_PENDING); ++ + if (dbg_kdb_mode) + kdb_printf("PANIC: %s\n", msg); + +-- +2.42.0 + diff --git a/queue-6.5/lib-generic-radix-tree.c-don-t-overflow-in-peek.patch b/queue-6.5/lib-generic-radix-tree.c-don-t-overflow-in-peek.patch new file mode 100644 index 00000000000..0bd854a59fc --- /dev/null +++ b/queue-6.5/lib-generic-radix-tree.c-don-t-overflow-in-peek.patch @@ -0,0 +1,84 @@ +From 9873cea6cacabb4eeec8501dbf49dc560e4eb5f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Feb 2021 20:11:25 -0500 +Subject: lib/generic-radix-tree.c: Don't overflow in peek() + +From: Kent Overstreet + +[ Upstream commit 9492261ff2460252cf2d8de89cdf854c7e2b28a0 ] + +When we started spreading new inode numbers throughout most of the 64 +bit inode space, that triggered some corner case bugs, in particular +some integer overflows related to the radix tree code. Oops. + +Signed-off-by: Kent Overstreet +Signed-off-by: Sasha Levin +--- + include/linux/generic-radix-tree.h | 7 +++++++ + lib/generic-radix-tree.c | 17 ++++++++++++++--- + 2 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/include/linux/generic-radix-tree.h b/include/linux/generic-radix-tree.h +index 107613f7d7920..f6cd0f909d9fb 100644 +--- a/include/linux/generic-radix-tree.h ++++ b/include/linux/generic-radix-tree.h +@@ -38,6 +38,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -184,6 +185,12 @@ void *__genradix_iter_peek(struct genradix_iter *, struct __genradix *, size_t); + static inline void __genradix_iter_advance(struct genradix_iter *iter, + size_t obj_size) + { ++ if (iter->offset + obj_size < iter->offset) { ++ iter->offset = SIZE_MAX; ++ iter->pos = SIZE_MAX; ++ return; ++ } ++ + iter->offset += obj_size; + + if (!is_power_of_2(obj_size) && +diff --git a/lib/generic-radix-tree.c b/lib/generic-radix-tree.c +index f25eb111c0516..7dfa88282b006 100644 +--- a/lib/generic-radix-tree.c ++++ b/lib/generic-radix-tree.c +@@ -166,6 +166,10 @@ void *__genradix_iter_peek(struct genradix_iter *iter, + struct genradix_root *r; + struct genradix_node *n; + unsigned level, i; ++ ++ if (iter->offset == SIZE_MAX) ++ return NULL; ++ + restart: + r = READ_ONCE(radix->root); + if (!r) +@@ -184,10 +188,17 @@ void *__genradix_iter_peek(struct genradix_iter *iter, + (GENRADIX_ARY - 1); + + while (!n->children[i]) { ++ size_t objs_per_ptr = genradix_depth_size(level); ++ ++ if (iter->offset + objs_per_ptr < iter->offset) { ++ iter->offset = SIZE_MAX; ++ iter->pos = SIZE_MAX; ++ return NULL; ++ } ++ + i++; +- iter->offset = round_down(iter->offset + +- genradix_depth_size(level), +- genradix_depth_size(level)); ++ iter->offset = round_down(iter->offset + objs_per_ptr, ++ objs_per_ptr); + iter->pos = (iter->offset >> PAGE_SHIFT) * + objs_per_page; + if (i == GENRADIX_ARY) +-- +2.42.0 + diff --git a/queue-6.5/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch b/queue-6.5/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch new file mode 100644 index 00000000000..e5b906cefed --- /dev/null +++ b/queue-6.5/locking-ww_mutex-test-fix-potential-workqueue-corrup.patch @@ -0,0 +1,119 @@ +From f864d6fddc7b4e1c99eec8591e46d6136912b378 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 04:36:00 +0000 +Subject: locking/ww_mutex/test: Fix potential workqueue corruption + +From: John Stultz + +[ Upstream commit bccdd808902f8c677317cec47c306e42b93b849e ] + +In some cases running with the test-ww_mutex code, I was seeing +odd behavior where sometimes it seemed flush_workqueue was +returning before all the work threads were finished. + +Often this would cause strange crashes as the mutexes would be +freed while they were being used. + +Looking at the code, there is a lifetime problem as the +controlling thread that spawns the work allocates the +"struct stress" structures that are passed to the workqueue +threads. Then when the workqueue threads are finished, +they free the stress struct that was passed to them. + +Unfortunately the workqueue work_struct node is in the stress +struct. Which means the work_struct is freed before the work +thread returns and while flush_workqueue is waiting. + +It seems like a better idea to have the controlling thread +both allocate and free the stress structures, so that we can +be sure we don't corrupt the workqueue by freeing the structure +prematurely. + +So this patch reworks the test to do so, and with this change +I no longer see the early flush_workqueue returns. + +Signed-off-by: John Stultz +Signed-off-by: Ingo Molnar +Link: https://lore.kernel.org/r/20230922043616.19282-3-jstultz@google.com +Signed-off-by: Sasha Levin +--- + kernel/locking/test-ww_mutex.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c +index 93cca6e698600..7c5a8f05497f2 100644 +--- a/kernel/locking/test-ww_mutex.c ++++ b/kernel/locking/test-ww_mutex.c +@@ -466,7 +466,6 @@ static void stress_inorder_work(struct work_struct *work) + } while (!time_after(jiffies, stress->timeout)); + + kfree(order); +- kfree(stress); + } + + struct reorder_lock { +@@ -531,7 +530,6 @@ static void stress_reorder_work(struct work_struct *work) + list_for_each_entry_safe(ll, ln, &locks, link) + kfree(ll); + kfree(order); +- kfree(stress); + } + + static void stress_one_work(struct work_struct *work) +@@ -552,8 +550,6 @@ static void stress_one_work(struct work_struct *work) + break; + } + } while (!time_after(jiffies, stress->timeout)); +- +- kfree(stress); + } + + #define STRESS_INORDER BIT(0) +@@ -564,15 +560,24 @@ static void stress_one_work(struct work_struct *work) + static int stress(int nlocks, int nthreads, unsigned int flags) + { + struct ww_mutex *locks; +- int n; ++ struct stress *stress_array; ++ int n, count; + + locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL); + if (!locks) + return -ENOMEM; + ++ stress_array = kmalloc_array(nthreads, sizeof(*stress_array), ++ GFP_KERNEL); ++ if (!stress_array) { ++ kfree(locks); ++ return -ENOMEM; ++ } ++ + for (n = 0; n < nlocks; n++) + ww_mutex_init(&locks[n], &ww_class); + ++ count = 0; + for (n = 0; nthreads; n++) { + struct stress *stress; + void (*fn)(struct work_struct *work); +@@ -596,9 +601,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags) + if (!fn) + continue; + +- stress = kmalloc(sizeof(*stress), GFP_KERNEL); +- if (!stress) +- break; ++ stress = &stress_array[count++]; + + INIT_WORK(&stress->work, fn); + stress->locks = locks; +@@ -613,6 +616,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags) + + for (n = 0; n < nlocks; n++) + ww_mutex_destroy(&locks[n]); ++ kfree(stress_array); + kfree(locks); + + return 0; +-- +2.42.0 + diff --git a/queue-6.5/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch b/queue-6.5/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch new file mode 100644 index 00000000000..9cd752f2638 --- /dev/null +++ b/queue-6.5/macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch @@ -0,0 +1,61 @@ +From 5afad0d5158223130bf53bb7c8313e8ca9ddbb76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 18:59:15 +0100 +Subject: macvlan: Don't propagate promisc change to lower dev in passthru + +From: Vlad Buslov + +[ Upstream commit 7e1caeace0418381f36b3aa8403dfd82fc57fc53 ] + +Macvlan device in passthru mode sets its lower device promiscuous mode +according to its MACVLAN_FLAG_NOPROMISC flag instead of synchronizing it to +its own promiscuity setting. However, macvlan_change_rx_flags() function +doesn't check the mode before propagating such changes to the lower device +which can cause net_device->promiscuity counter overflow as illustrated by +reproduction example [0] and resulting dmesg log [1]. Fix the issue by +first verifying the mode in macvlan_change_rx_flags() function before +propagating promiscuous mode change to the lower device. + +[0]: +ip link add macvlan1 link enp8s0f0 type macvlan mode passthru +ip link set macvlan1 promisc on +ip l set dev macvlan1 up +ip link set macvlan1 promisc off +ip l set dev macvlan1 down +ip l set dev macvlan1 up + +[1]: +[ 5156.281724] macvlan1: entered promiscuous mode +[ 5156.285467] mlx5_core 0000:08:00.0 enp8s0f0: entered promiscuous mode +[ 5156.287639] macvlan1: left promiscuous mode +[ 5156.288339] mlx5_core 0000:08:00.0 enp8s0f0: left promiscuous mode +[ 5156.290907] mlx5_core 0000:08:00.0 enp8s0f0: entered promiscuous mode +[ 5156.317197] mlx5_core 0000:08:00.0 enp8s0f0: promiscuity touches roof, set promiscuity failed. promiscuity feature of device might be broken. + +Fixes: efdbd2b30caa ("macvlan: Propagate promiscuity setting to lower devices.") +Reviewed-by: Gal Pressman +Signed-off-by: Vlad Buslov +Reviewed-by: Jiri Pirko +Link: https://lore.kernel.org/r/20231114175915.1649154-1-vladbu@nvidia.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/macvlan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index ed908165a8b4e..347f288350619 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -780,7 +780,7 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change) + if (dev->flags & IFF_UP) { + if (change & IFF_ALLMULTI) + dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); +- if (change & IFF_PROMISC) ++ if (!macvlan_passthru(vlan->port) && change & IFF_PROMISC) + dev_set_promiscuity(lowerdev, + dev->flags & IFF_PROMISC ? 1 : -1); + +-- +2.42.0 + diff --git a/queue-6.5/md-don-t-rely-on-mddev-pers-to-be-set-in-mddev_suspe.patch b/queue-6.5/md-don-t-rely-on-mddev-pers-to-be-set-in-mddev_suspe.patch new file mode 100644 index 00000000000..485cf92b07d --- /dev/null +++ b/queue-6.5/md-don-t-rely-on-mddev-pers-to-be-set-in-mddev_suspe.patch @@ -0,0 +1,43 @@ +From e73ed3fd44abfa25bb2add28a0d1a5bef81b0040 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 11:09:52 +0800 +Subject: md: don't rely on 'mddev->pers' to be set in mddev_suspend() + +From: Yu Kuai + +[ Upstream commit b721e7885eb242aa2459ee66bb42ceef1bcf0f0c ] + +'active_io' used to be initialized while the array is running, and +'mddev->pers' is set while the array is running as well. Hence caller +must hold 'reconfig_mutex' and guarantee 'mddev->pers' is set before +calling mddev_suspend(). + +Now that 'active_io' is initialized when mddev is allocated, such +restriction doesn't exist anymore. In the meantime, follow up patches +will refactor mddev_suspend(), hence add checking for 'mddev->pers' to +prevent null-ptr-deref. + +Signed-off-by: Yu Kuai +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20230825030956.1527023-4-yukuai1@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 78d51dddf3a00..34b7196d9634c 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -449,7 +449,7 @@ void mddev_suspend(struct mddev *mddev) + set_bit(MD_ALLOW_SB_UPDATE, &mddev->flags); + percpu_ref_kill(&mddev->active_io); + +- if (mddev->pers->prepare_suspend) ++ if (mddev->pers && mddev->pers->prepare_suspend) + mddev->pers->prepare_suspend(mddev); + + wait_event(mddev->sb_wait, percpu_ref_is_zero(&mddev->active_io)); +-- +2.42.0 + diff --git a/queue-6.5/media-ccs-fix-driver-quirk-struct-documentation.patch b/queue-6.5/media-ccs-fix-driver-quirk-struct-documentation.patch new file mode 100644 index 00000000000..216242d9bd7 --- /dev/null +++ b/queue-6.5/media-ccs-fix-driver-quirk-struct-documentation.patch @@ -0,0 +1,42 @@ +From 35db690f4db0d928c85f06a84ee747cce2a9367f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 15:18:18 +0300 +Subject: media: ccs: Fix driver quirk struct documentation + +From: Sakari Ailus + +[ Upstream commit 441b5c63d71ec9ec5453328f7e83384ecc1dddd9 ] + +Fix documentation for struct ccs_quirk, a device specific struct for +managing deviations from the standard. The flags field was drifted away +from where it should have been. + +Signed-off-by: Sakari Ailus +Reviewed-by: Laurent Pinchart +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ccs/ccs-quirk.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h +index 5838fcda92fd4..0b1a64958d714 100644 +--- a/drivers/media/i2c/ccs/ccs-quirk.h ++++ b/drivers/media/i2c/ccs/ccs-quirk.h +@@ -32,12 +32,10 @@ struct ccs_sensor; + * @reg: Pointer to the register to access + * @value: Register value, set by the caller on write, or + * by the quirk on read +- * +- * @flags: Quirk flags +- * + * @return: 0 on success, -ENOIOCTLCMD if no register + * access may be done by the caller (default read + * value is zero), else negative error code on error ++ * @flags: Quirk flags + */ + struct ccs_quirk { + int (*limits)(struct ccs_sensor *sensor); +-- +2.42.0 + diff --git a/queue-6.5/media-cobalt-use-field_get-to-extract-link-width.patch b/queue-6.5/media-cobalt-use-field_get-to-extract-link-width.patch new file mode 100644 index 00000000000..13b25609335 --- /dev/null +++ b/queue-6.5/media-cobalt-use-field_get-to-extract-link-width.patch @@ -0,0 +1,77 @@ +From dce44dfc529f9ca565b0bf11d3139694d7caf4ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 15:27:40 +0300 +Subject: media: cobalt: Use FIELD_GET() to extract Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit f301fedbeecfdce91cb898d6fa5e62f269801fee ] + +Use FIELD_GET() to extract PCIe Negotiated and Maximum Link Width fields +instead of custom masking and shifting. + +Signed-off-by: Ilpo Järvinen +Reviewed-by: Jonathan Cameron +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/pci/cobalt/cobalt-driver.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c +index 74edcc76d12f4..6e1a0614e6d06 100644 +--- a/drivers/media/pci/cobalt/cobalt-driver.c ++++ b/drivers/media/pci/cobalt/cobalt-driver.c +@@ -8,6 +8,7 @@ + * All rights reserved. + */ + ++#include + #include + #include + #include +@@ -210,17 +211,17 @@ void cobalt_pcie_status_show(struct cobalt *cobalt) + pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &stat); + cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n", + capa, get_link_speed(capa), +- (capa & PCI_EXP_LNKCAP_MLW) >> 4); ++ FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); + cobalt_info("PCIe link control 0x%04x\n", ctrl); + cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n", + stat, get_link_speed(stat), +- (stat & PCI_EXP_LNKSTA_NLW) >> 4); ++ FIELD_GET(PCI_EXP_LNKSTA_NLW, stat)); + + /* Bus */ + pcie_capability_read_dword(pci_bus_dev, PCI_EXP_LNKCAP, &capa); + cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n", + capa, get_link_speed(capa), +- (capa & PCI_EXP_LNKCAP_MLW) >> 4); ++ FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); + + /* Slot */ + pcie_capability_read_dword(pci_dev, PCI_EXP_SLTCAP, &capa); +@@ -239,7 +240,7 @@ static unsigned pcie_link_get_lanes(struct cobalt *cobalt) + if (!pci_is_pcie(pci_dev)) + return 0; + pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &link); +- return (link & PCI_EXP_LNKSTA_NLW) >> 4; ++ return FIELD_GET(PCI_EXP_LNKSTA_NLW, link); + } + + static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) +@@ -250,7 +251,7 @@ static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) + if (!pci_is_pcie(pci_dev)) + return 0; + pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &link); +- return (link & PCI_EXP_LNKCAP_MLW) >> 4; ++ return FIELD_GET(PCI_EXP_LNKCAP_MLW, link); + } + + static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev) +-- +2.42.0 + diff --git a/queue-6.5/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch b/queue-6.5/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch new file mode 100644 index 00000000000..7324ea27019 --- /dev/null +++ b/queue-6.5/media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch @@ -0,0 +1,53 @@ +From 1594a086229a9ece8c57adf64f261ca993dd6891 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 13:14:01 +0530 +Subject: media: gspca: cpia1: shift-out-of-bounds in set_flicker + +From: Rajeshwar R Shinde + +[ Upstream commit 099be1822d1f095433f4b08af9cc9d6308ec1953 ] + +Syzkaller reported the following issue: +UBSAN: shift-out-of-bounds in drivers/media/usb/gspca/cpia1.c:1031:27 +shift exponent 245 is too large for 32-bit type 'int' + +When the value of the variable "sd->params.exposure.gain" exceeds the +number of bits in an integer, a shift-out-of-bounds error is reported. It +is triggered because the variable "currentexp" cannot be left-shifted by +more than the number of bits in an integer. In order to avoid invalid +range during left-shift, the conditional expression is added. + +Reported-by: syzbot+e27f3dbdab04e43b9f73@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/20230818164522.12806-1-coolrrsh@gmail.com +Link: https://syzkaller.appspot.com/bug?extid=e27f3dbdab04e43b9f73 +Signed-off-by: Rajeshwar R Shinde +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/usb/gspca/cpia1.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c +index 46ed95483e222..5f5fa851ca640 100644 +--- a/drivers/media/usb/gspca/cpia1.c ++++ b/drivers/media/usb/gspca/cpia1.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + + #include "gspca.h" + +@@ -1028,6 +1029,8 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) + sd->params.exposure.expMode = 2; + sd->exposure_status = EXPOSURE_NORMAL; + } ++ if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp)) ++ return -EINVAL; + currentexp = currentexp << sd->params.exposure.gain; + sd->params.exposure.gain = 0; + /* round down current exposure to nearest value */ +-- +2.42.0 + diff --git a/queue-6.5/media-imon-fix-access-to-invalid-resource-for-the-se.patch b/queue-6.5/media-imon-fix-access-to-invalid-resource-for-the-se.patch new file mode 100644 index 00000000000..d9dd962ad63 --- /dev/null +++ b/queue-6.5/media-imon-fix-access-to-invalid-resource-for-the-se.patch @@ -0,0 +1,54 @@ +From 1f4b3d26b39a9a18cea64b8a2e2fab818e5beb06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 14:38:07 +0200 +Subject: media: imon: fix access to invalid resource for the second interface + +From: Takashi Iwai + +[ Upstream commit a1766a4fd83befa0b34d932d532e7ebb7fab1fa7 ] + +imon driver probes two USB interfaces, and at the probe of the second +interface, the driver assumes blindly that the first interface got +bound with the same imon driver. It's usually true, but it's still +possible that the first interface is bound with another driver via a +malformed descriptor. Then it may lead to a memory corruption, as +spotted by syzkaller; imon driver accesses the data from drvdata as +struct imon_context object although it's a completely different one +that was assigned by another driver. + +This patch adds a sanity check -- whether the first interface is +really bound with the imon driver or not -- for avoiding the problem +above at the probe time. + +Reported-by: syzbot+59875ffef5cb9c9b29e9@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/000000000000a838aa0603cc74d6@google.com/ +Tested-by: Ricardo B. Marliere +Link: https://lore.kernel.org/r/20230922005152.163640-1-ricardo@marliere.net +Signed-off-by: Takashi Iwai +Signed-off-by: Sean Young +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/rc/imon.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c +index 74546f7e34691..5719dda6e0f0e 100644 +--- a/drivers/media/rc/imon.c ++++ b/drivers/media/rc/imon.c +@@ -2427,6 +2427,12 @@ static int imon_probe(struct usb_interface *interface, + goto fail; + } + ++ if (first_if->dev.driver != interface->dev.driver) { ++ dev_err(&interface->dev, "inconsistent driver matching\n"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ + if (ifnum == 0) { + ictx = imon_init_intf0(interface, id); + if (!ictx) { +-- +2.42.0 + diff --git a/queue-6.5/media-ipu-bridge-increase-sensor_name-size.patch b/queue-6.5/media-ipu-bridge-increase-sensor_name-size.patch new file mode 100644 index 00000000000..46ca74d25c2 --- /dev/null +++ b/queue-6.5/media-ipu-bridge-increase-sensor_name-size.patch @@ -0,0 +1,67 @@ +From 098b0c7e116654bc1edff5cfafdc21169e8139ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 17:20:49 +0200 +Subject: media: ipu-bridge: increase sensor_name size + +From: Hans Verkuil + +[ Upstream commit 83d0d4cc1423194b580356966107379490edd02e ] + +Fixes this compiler warning: + +In file included from include/linux/property.h:14, + from include/linux/acpi.h:16, + from drivers/media/pci/intel/ipu-bridge.c:4: +In function 'ipu_bridge_init_swnode_names', + inlined from 'ipu_bridge_create_connection_swnodes' at drivers/media/pci/intel/ipu-bridge.c:445:2, + inlined from 'ipu_bridge_connect_sensor' at drivers/media/pci/intel/ipu-bridge.c:656:3: +include/linux/fwnode.h:81:49: warning: '%u' directive output may be truncated writing between 1 and 3 bytes into a region of size 2 [-Wformat-truncation=] + 81 | #define SWNODE_GRAPH_PORT_NAME_FMT "port@%u" + | ^~~~~~~~~ +drivers/media/pci/intel/ipu-bridge.c:384:18: note: in expansion of macro 'SWNODE_GRAPH_PORT_NAME_FMT' + 384 | SWNODE_GRAPH_PORT_NAME_FMT, sensor->link); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~ +include/linux/fwnode.h: In function 'ipu_bridge_connect_sensor': +include/linux/fwnode.h:81:55: note: format string is defined here + 81 | #define SWNODE_GRAPH_PORT_NAME_FMT "port@%u" + | ^~ +In function 'ipu_bridge_init_swnode_names', + inlined from 'ipu_bridge_create_connection_swnodes' at drivers/media/pci/intel/ipu-bridge.c:445:2, + inlined from 'ipu_bridge_connect_sensor' at drivers/media/pci/intel/ipu-bridge.c:656:3: +include/linux/fwnode.h:81:49: note: directive argument in the range [0, 255] + 81 | #define SWNODE_GRAPH_PORT_NAME_FMT "port@%u" + | ^~~~~~~~~ +drivers/media/pci/intel/ipu-bridge.c:384:18: note: in expansion of macro 'SWNODE_GRAPH_PORT_NAME_FMT' + 384 | SWNODE_GRAPH_PORT_NAME_FMT, sensor->link); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/media/pci/intel/ipu-bridge.c:382:9: note: 'snprintf' output between 7 and 9 bytes into a destination of size 7 + 382 | snprintf(sensor->node_names.remote_port, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 383 | sizeof(sensor->node_names.remote_port), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 384 | SWNODE_GRAPH_PORT_NAME_FMT, sensor->link); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Hans Verkuil +Acked-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + drivers/media/pci/intel/ipu-bridge.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/pci/intel/ipu-bridge.h b/drivers/media/pci/intel/ipu-bridge.h +index 1ff0b2d04d929..1ed53d51e16a1 100644 +--- a/drivers/media/pci/intel/ipu-bridge.h ++++ b/drivers/media/pci/intel/ipu-bridge.h +@@ -103,7 +103,7 @@ struct ipu_property_names { + struct ipu_node_names { + char port[7]; + char endpoint[11]; +- char remote_port[7]; ++ char remote_port[9]; + char vcm[16]; + }; + +-- +2.42.0 + diff --git a/queue-6.5/media-vivid-avoid-integer-overflow.patch b/queue-6.5/media-vivid-avoid-integer-overflow.patch new file mode 100644 index 00000000000..b2951973079 --- /dev/null +++ b/queue-6.5/media-vivid-avoid-integer-overflow.patch @@ -0,0 +1,47 @@ +From 57389d697fbe22ff78cc973072e45f328ccc7972 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 17:20:48 +0200 +Subject: media: vivid: avoid integer overflow + +From: Hans Verkuil + +[ Upstream commit 4567ebf8e8f9546b373e78e3b7d584cc30b62028 ] + +Fixes these compiler warnings: + +drivers/media/test-drivers/vivid/vivid-rds-gen.c: In function 'vivid_rds_gen_fill': +drivers/media/test-drivers/vivid/vivid-rds-gen.c:147:56: warning: '.' directive output may be truncated writing 1 byte into a region of size between 0 and 3 [-Wformat-truncation=] + 147 | snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", + | ^ +drivers/media/test-drivers/vivid/vivid-rds-gen.c:147:52: note: directive argument in the range [0, 9] + 147 | snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", + | ^~~~~~~~~ +drivers/media/test-drivers/vivid/vivid-rds-gen.c:147:9: note: 'snprintf' output between 9 and 12 bytes into a destination of size 9 + 147 | snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 148 | freq / 16, ((freq & 0xf) * 10) / 16); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Hans Verkuil +Acked-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + drivers/media/test-drivers/vivid/vivid-rds-gen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/test-drivers/vivid/vivid-rds-gen.c b/drivers/media/test-drivers/vivid/vivid-rds-gen.c +index b5b104ee64c99..c57771119a34b 100644 +--- a/drivers/media/test-drivers/vivid/vivid-rds-gen.c ++++ b/drivers/media/test-drivers/vivid/vivid-rds-gen.c +@@ -145,7 +145,7 @@ void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq, + rds->ta = alt; + rds->ms = true; + snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", +- freq / 16, ((freq & 0xf) * 10) / 16); ++ (freq / 16) % 1000000, (((freq & 0xf) * 10) / 16) % 10); + if (alt) + strscpy(rds->radiotext, + " The Radio Data System can switch between different Radio Texts ", +-- +2.42.0 + diff --git a/queue-6.5/mfd-intel-lpss-add-intel-lunar-lake-m-pci-ids.patch b/queue-6.5/mfd-intel-lpss-add-intel-lunar-lake-m-pci-ids.patch new file mode 100644 index 00000000000..5007b28638c --- /dev/null +++ b/queue-6.5/mfd-intel-lpss-add-intel-lunar-lake-m-pci-ids.patch @@ -0,0 +1,46 @@ +From 8a1941929c635df318593d649188c5ffc8c79c15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 11:33:44 +0300 +Subject: mfd: intel-lpss: Add Intel Lunar Lake-M PCI IDs + +From: Jarkko Nikula + +[ Upstream commit e53b22b10c6e0de0cf2a03a92b18fdad70f266c7 ] + +Add Intel Lunar Lake-M SoC PCI IDs. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20231002083344.75611-1-jarkko.nikula@linux.intel.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/intel-lpss-pci.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c +index 699f44ffff0e4..ae5759200622c 100644 +--- a/drivers/mfd/intel-lpss-pci.c ++++ b/drivers/mfd/intel-lpss-pci.c +@@ -561,6 +561,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0xa3e2), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa3e3), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa3e6), (kernel_ulong_t)&spt_uart_info }, ++ /* LNL-M */ ++ { PCI_VDEVICE(INTEL, 0xa825), (kernel_ulong_t)&bxt_uart_info }, ++ { PCI_VDEVICE(INTEL, 0xa826), (kernel_ulong_t)&bxt_uart_info }, ++ { PCI_VDEVICE(INTEL, 0xa827), (kernel_ulong_t)&tgl_info }, ++ { PCI_VDEVICE(INTEL, 0xa830), (kernel_ulong_t)&tgl_info }, ++ { PCI_VDEVICE(INTEL, 0xa846), (kernel_ulong_t)&tgl_info }, ++ { PCI_VDEVICE(INTEL, 0xa850), (kernel_ulong_t)&ehl_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0xa851), (kernel_ulong_t)&ehl_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0xa852), (kernel_ulong_t)&bxt_uart_info }, ++ { PCI_VDEVICE(INTEL, 0xa878), (kernel_ulong_t)&ehl_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0xa879), (kernel_ulong_t)&ehl_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0xa87a), (kernel_ulong_t)&ehl_i2c_info }, ++ { PCI_VDEVICE(INTEL, 0xa87b), (kernel_ulong_t)&ehl_i2c_info }, + { } + }; + MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); +-- +2.42.0 + diff --git a/queue-6.5/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch b/queue-6.5/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch new file mode 100644 index 00000000000..a47cc87e302 --- /dev/null +++ b/queue-6.5/misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch @@ -0,0 +1,49 @@ +From 3ff0ff795ebe4bc20cf143b048726af2d6968a83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 17:56:31 +0900 +Subject: misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yoshihiro Shimoda + +[ Upstream commit 6c4b39937f4e65688ea294725ae432b2565821ff ] + +Add Renesas R8A779F0 in pci_device_id table so that pci-epf-test +can be used for testing PCIe EP on R-Car S4-8. + +Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-16-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Krzysztof Wilczyński +Acked-by: Manivannan Sadhasivam +Signed-off-by: Sasha Levin +--- + drivers/misc/pci_endpoint_test.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c +index 7e1acc68d4359..af519088732d9 100644 +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -82,6 +82,7 @@ + #define PCI_DEVICE_ID_RENESAS_R8A774B1 0x002b + #define PCI_DEVICE_ID_RENESAS_R8A774C0 0x002d + #define PCI_DEVICE_ID_RENESAS_R8A774E1 0x0025 ++#define PCI_DEVICE_ID_RENESAS_R8A779F0 0x0031 + + static DEFINE_IDA(pci_endpoint_test_ida); + +@@ -991,6 +992,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774B1),}, + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774C0),}, + { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774E1),}, ++ { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A779F0), ++ .driver_data = (kernel_ulong_t)&default_data, ++ }, + { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E), + .driver_data = (kernel_ulong_t)&j721e_data, + }, +-- +2.42.0 + diff --git a/queue-6.5/mtd-rawnand-intel-check-return-value-of-devm_kasprin.patch b/queue-6.5/mtd-rawnand-intel-check-return-value-of-devm_kasprin.patch new file mode 100644 index 00000000000..24638510187 --- /dev/null +++ b/queue-6.5/mtd-rawnand-intel-check-return-value-of-devm_kasprin.patch @@ -0,0 +1,53 @@ +From 26fc3ae54cbc49a88385c9a026a4d6aa842f93c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 06:55:37 +0000 +Subject: mtd: rawnand: intel: check return value of devm_kasprintf() + +From: Yi Yang + +[ Upstream commit 74ac5b5e2375f1e8ef797ac7770887e9969f2516 ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. Ensure the allocation was successful by +checking the pointer validity. + +Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") +Signed-off-by: Yi Yang +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20231019065537.318391-1-yiyang13@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/intel-nand-controller.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c +index a9909eb081244..8231e9828dce7 100644 +--- a/drivers/mtd/nand/raw/intel-nand-controller.c ++++ b/drivers/mtd/nand/raw/intel-nand-controller.c +@@ -619,6 +619,11 @@ static int ebu_nand_probe(struct platform_device *pdev) + ebu_host->cs_num = cs; + + resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs); ++ if (!resname) { ++ ret = -ENOMEM; ++ goto err_of_node_put; ++ } ++ + ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev, + resname); + if (IS_ERR(ebu_host->cs[cs].chipaddr)) { +@@ -655,6 +660,11 @@ static int ebu_nand_probe(struct platform_device *pdev) + } + + resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs); ++ if (!resname) { ++ ret = -ENOMEM; ++ goto err_cleanup_dma; ++ } ++ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname); + if (!res) { + ret = -EINVAL; +-- +2.42.0 + diff --git a/queue-6.5/mtd-rawnand-meson-check-return-value-of-devm_kasprin.patch b/queue-6.5/mtd-rawnand-meson-check-return-value-of-devm_kasprin.patch new file mode 100644 index 00000000000..f1e5534e81a --- /dev/null +++ b/queue-6.5/mtd-rawnand-meson-check-return-value-of-devm_kasprin.patch @@ -0,0 +1,39 @@ +From 13a1a961bd589ac1964549b8ef50bfac573b1ce5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 06:55:48 +0000 +Subject: mtd: rawnand: meson: check return value of devm_kasprintf() + +From: Yi Yang + +[ Upstream commit 5a985960a4dd041c21dbe9956958c1633d2da706 ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. Ensure the allocation was successful by +checking the pointer validity. + +Fixes: 1e4d3ba66888 ("mtd: rawnand: meson: fix the clock") +Signed-off-by: Yi Yang +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20231019065548.318443-1-yiyang13@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/meson_nand.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c +index b10011dec1e62..b16adc0e92e9d 100644 +--- a/drivers/mtd/nand/raw/meson_nand.c ++++ b/drivers/mtd/nand/raw/meson_nand.c +@@ -1115,6 +1115,9 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc) + init.name = devm_kasprintf(nfc->dev, + GFP_KERNEL, "%s#div", + dev_name(nfc->dev)); ++ if (!init.name) ++ return -ENOMEM; ++ + init.ops = &clk_divider_ops; + nfc_divider_parent_data[0].fw_name = "device"; + init.parent_data = nfc_divider_parent_data; +-- +2.42.0 + diff --git a/queue-6.5/mtd-rawnand-tegra-add-missing-check-for-platform_get.patch b/queue-6.5/mtd-rawnand-tegra-add-missing-check-for-platform_get.patch new file mode 100644 index 00000000000..151c4e0622f --- /dev/null +++ b/queue-6.5/mtd-rawnand-tegra-add-missing-check-for-platform_get.patch @@ -0,0 +1,39 @@ +From 4b7d6c0d154f8b5aaf6d51d972682fe20955b739 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 16:40:46 +0800 +Subject: mtd: rawnand: tegra: add missing check for platform_get_irq() + +From: Yi Yang + +[ Upstream commit 0a1166c27d4e53186e6bf9147ea6db9cd1d65847 ] + +Add the missing check for platform_get_irq() and return error code +if it fails. + +Fixes: d7d9f8ec77fe ("mtd: rawnand: add NVIDIA Tegra NAND Flash controller driver") +Signed-off-by: Yi Yang +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230821084046.217025-1-yiyang13@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/tegra_nand.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c +index eb0b9d16e8dae..a553e3ac8ff41 100644 +--- a/drivers/mtd/nand/raw/tegra_nand.c ++++ b/drivers/mtd/nand/raw/tegra_nand.c +@@ -1197,6 +1197,10 @@ static int tegra_nand_probe(struct platform_device *pdev) + init_completion(&ctrl->dma_complete); + + ctrl->irq = platform_get_irq(pdev, 0); ++ if (ctrl->irq < 0) { ++ err = ctrl->irq; ++ goto err_put_pm; ++ } + err = devm_request_irq(&pdev->dev, ctrl->irq, tegra_nand_irq, 0, + dev_name(&pdev->dev), ctrl); + if (err) { +-- +2.42.0 + diff --git a/queue-6.5/net-annotate-data-races-around-sk-sk_dst_pending_con.patch b/queue-6.5/net-annotate-data-races-around-sk-sk_dst_pending_con.patch new file mode 100644 index 00000000000..c32caaca53f --- /dev/null +++ b/queue-6.5/net-annotate-data-races-around-sk-sk_dst_pending_con.patch @@ -0,0 +1,82 @@ +From cce1c0fa2ddede9124db9906e7cb527c7c1d71dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 20:28:18 +0000 +Subject: net: annotate data-races around sk->sk_dst_pending_confirm + +From: Eric Dumazet + +[ Upstream commit eb44ad4e635132754bfbcb18103f1dcb7058aedd ] + +This field can be read or written without socket lock being held. + +Add annotations to avoid load-store tearing. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 6 +++--- + net/core/sock.c | 2 +- + net/ipv4/tcp_output.c | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index df19f99d26357..b9f0ef4bb527a 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2181,7 +2181,7 @@ static inline void __dst_negative_advice(struct sock *sk) + if (ndst != dst) { + rcu_assign_pointer(sk->sk_dst_cache, ndst); + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + } + } + } +@@ -2198,7 +2198,7 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst) + struct dst_entry *old_dst; + + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + old_dst = rcu_dereference_protected(sk->sk_dst_cache, + lockdep_sock_is_held(sk)); + rcu_assign_pointer(sk->sk_dst_cache, dst); +@@ -2211,7 +2211,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst) + struct dst_entry *old_dst; + + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst); + dst_release(old_dst); + } +diff --git a/net/core/sock.c b/net/core/sock.c +index eef27812013a4..6df04c705200a 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -600,7 +600,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) + INDIRECT_CALL_INET(dst->ops->check, ip6_dst_check, ipv4_dst_check, + dst, cookie) == NULL) { + sk_tx_queue_clear(sk); +- sk->sk_dst_pending_confirm = 0; ++ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); + RCU_INIT_POINTER(sk->sk_dst_cache, NULL); + dst_release(dst); + return NULL; +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index afa819eede6a3..c2403fea8ec9a 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1316,7 +1316,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, + skb->destructor = skb_is_tcp_pure_ack(skb) ? __sock_wfree : tcp_wfree; + refcount_add(skb->truesize, &sk->sk_wmem_alloc); + +- skb_set_dst_pending_confirm(skb, sk->sk_dst_pending_confirm); ++ skb_set_dst_pending_confirm(skb, READ_ONCE(sk->sk_dst_pending_confirm)); + + /* Build TCP header and checksum it. */ + th = (struct tcphdr *)skb->data; +-- +2.42.0 + diff --git a/queue-6.5/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch b/queue-6.5/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch new file mode 100644 index 00000000000..9ff23c76a40 --- /dev/null +++ b/queue-6.5/net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch @@ -0,0 +1,65 @@ +From 623f68dff2f5f0c43b41bb5ed920d3a3eacb9660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 20:28:17 +0000 +Subject: net: annotate data-races around sk->sk_tx_queue_mapping + +From: Eric Dumazet + +[ Upstream commit 0bb4d124d34044179b42a769a0c76f389ae973b6 ] + +This field can be read or written without socket lock being held. + +Add annotations to avoid load-store tearing. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index fc189910e63fc..df19f99d26357 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2006,21 +2006,33 @@ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue) + /* sk_tx_queue_mapping accept only upto a 16-bit value */ + if (WARN_ON_ONCE((unsigned short)tx_queue >= USHRT_MAX)) + return; +- sk->sk_tx_queue_mapping = tx_queue; ++ /* Paired with READ_ONCE() in sk_tx_queue_get() and ++ * other WRITE_ONCE() because socket lock might be not held. ++ */ ++ WRITE_ONCE(sk->sk_tx_queue_mapping, tx_queue); + } + + #define NO_QUEUE_MAPPING USHRT_MAX + + static inline void sk_tx_queue_clear(struct sock *sk) + { +- sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING; ++ /* Paired with READ_ONCE() in sk_tx_queue_get() and ++ * other WRITE_ONCE() because socket lock might be not held. ++ */ ++ WRITE_ONCE(sk->sk_tx_queue_mapping, NO_QUEUE_MAPPING); + } + + static inline int sk_tx_queue_get(const struct sock *sk) + { +- if (sk && sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING) +- return sk->sk_tx_queue_mapping; ++ if (sk) { ++ /* Paired with WRITE_ONCE() in sk_tx_queue_clear() ++ * and sk_tx_queue_set(). ++ */ ++ int val = READ_ONCE(sk->sk_tx_queue_mapping); + ++ if (val != NO_QUEUE_MAPPING) ++ return val; ++ } + return -1; + } + +-- +2.42.0 + diff --git a/queue-6.5/net-ethernet-cortina-fix-max-rx-frame-define.patch b/queue-6.5/net-ethernet-cortina-fix-max-rx-frame-define.patch new file mode 100644 index 00000000000..ed45e577f6d --- /dev/null +++ b/queue-6.5/net-ethernet-cortina-fix-max-rx-frame-define.patch @@ -0,0 +1,55 @@ +From 642493abf8fc429b4691e739c7f38cc36437ab90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 10:03:12 +0100 +Subject: net: ethernet: cortina: Fix max RX frame define + +From: Linus Walleij + +[ Upstream commit 510e35fb931ffc3b100e5d5ae4595cd3beca9f1a ] + +Enumerator 3 is 1548 bytes according to the datasheet. +Not 1542. + +Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") +Reviewed-by: Andrew Lunn +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20231109-gemini-largeframe-fix-v4-1-6e611528db08@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cortina/gemini.c | 4 ++-- + drivers/net/ethernet/cortina/gemini.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index 5715b9ab2712e..9fe8d22a26719 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -432,8 +432,8 @@ static const struct gmac_max_framelen gmac_maxlens[] = { + .val = CONFIG0_MAXLEN_1536, + }, + { +- .max_l3_len = 1542, +- .val = CONFIG0_MAXLEN_1542, ++ .max_l3_len = 1548, ++ .val = CONFIG0_MAXLEN_1548, + }, + { + .max_l3_len = 9212, +diff --git a/drivers/net/ethernet/cortina/gemini.h b/drivers/net/ethernet/cortina/gemini.h +index 9fdf77d5eb374..99efb11557436 100644 +--- a/drivers/net/ethernet/cortina/gemini.h ++++ b/drivers/net/ethernet/cortina/gemini.h +@@ -787,7 +787,7 @@ union gmac_config0 { + #define CONFIG0_MAXLEN_1536 0 + #define CONFIG0_MAXLEN_1518 1 + #define CONFIG0_MAXLEN_1522 2 +-#define CONFIG0_MAXLEN_1542 3 ++#define CONFIG0_MAXLEN_1548 3 + #define CONFIG0_MAXLEN_9k 4 /* 9212 */ + #define CONFIG0_MAXLEN_10k 5 /* 10236 */ + #define CONFIG0_MAXLEN_1518__6 6 +-- +2.42.0 + diff --git a/queue-6.5/net-ethernet-cortina-fix-mtu-max-setting.patch b/queue-6.5/net-ethernet-cortina-fix-mtu-max-setting.patch new file mode 100644 index 00000000000..bc41d8eff10 --- /dev/null +++ b/queue-6.5/net-ethernet-cortina-fix-mtu-max-setting.patch @@ -0,0 +1,91 @@ +From 79efe9204fed224c5e785a7b868e59e33afb2ee1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 10:03:14 +0100 +Subject: net: ethernet: cortina: Fix MTU max setting + +From: Linus Walleij + +[ Upstream commit dc6c0bfbaa947dd7976e30e8c29b10c868b6fa42 ] + +The RX max frame size is over 10000 for the Gemini ethernet, +but the TX max frame size is actually just 2047 (0x7ff after +checking the datasheet). Reflect this in what we offer to Linux, +cap the MTU at the TX max frame minus ethernet headers. + +We delete the code disabling the hardware checksum for large +MTUs as netdev->mtu can no longer be larger than +netdev->max_mtu meaning the if()-clause in gmac_fix_features() +is never true. + +Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") +Reviewed-by: Andrew Lunn +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20231109-gemini-largeframe-fix-v4-3-6e611528db08@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cortina/gemini.c | 17 ++++------------- + drivers/net/ethernet/cortina/gemini.h | 2 +- + 2 files changed, 5 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index a2d4ace01ed3c..e7137b468f5bc 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -2000,15 +2000,6 @@ static int gmac_change_mtu(struct net_device *netdev, int new_mtu) + return 0; + } + +-static netdev_features_t gmac_fix_features(struct net_device *netdev, +- netdev_features_t features) +-{ +- if (netdev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) +- features &= ~GMAC_OFFLOAD_FEATURES; +- +- return features; +-} +- + static int gmac_set_features(struct net_device *netdev, + netdev_features_t features) + { +@@ -2234,7 +2225,6 @@ static const struct net_device_ops gmac_351x_ops = { + .ndo_set_mac_address = gmac_set_mac_address, + .ndo_get_stats64 = gmac_get_stats64, + .ndo_change_mtu = gmac_change_mtu, +- .ndo_fix_features = gmac_fix_features, + .ndo_set_features = gmac_set_features, + }; + +@@ -2486,11 +2476,12 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev) + + netdev->hw_features = GMAC_OFFLOAD_FEATURES; + netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; +- /* We can handle jumbo frames up to 10236 bytes so, let's accept +- * payloads of 10236 bytes minus VLAN and ethernet header ++ /* We can receive jumbo frames up to 10236 bytes but only ++ * transmit 2047 bytes so, let's accept payloads of 2047 ++ * bytes minus VLAN and ethernet header + */ + netdev->min_mtu = ETH_MIN_MTU; +- netdev->max_mtu = 10236 - VLAN_ETH_HLEN; ++ netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; + + port->freeq_refill = 0; + netif_napi_add(netdev, &port->napi, gmac_napi_poll); +diff --git a/drivers/net/ethernet/cortina/gemini.h b/drivers/net/ethernet/cortina/gemini.h +index 99efb11557436..24bb989981f23 100644 +--- a/drivers/net/ethernet/cortina/gemini.h ++++ b/drivers/net/ethernet/cortina/gemini.h +@@ -502,7 +502,7 @@ union gmac_txdesc_3 { + #define SOF_BIT 0x80000000 + #define EOF_BIT 0x40000000 + #define EOFIE_BIT BIT(29) +-#define MTU_SIZE_BIT_MASK 0x1fff ++#define MTU_SIZE_BIT_MASK 0x7ff /* Max MTU 2047 bytes */ + + /* GMAC Tx Descriptor */ + struct gmac_txdesc { +-- +2.42.0 + diff --git a/queue-6.5/net-ethernet-cortina-handle-large-frames.patch b/queue-6.5/net-ethernet-cortina-handle-large-frames.patch new file mode 100644 index 00000000000..fb609a32591 --- /dev/null +++ b/queue-6.5/net-ethernet-cortina-handle-large-frames.patch @@ -0,0 +1,111 @@ +From 73b34a28c8c8b057020a6019a3c9292c68efc3c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 10:03:13 +0100 +Subject: net: ethernet: cortina: Handle large frames + +From: Linus Walleij + +[ Upstream commit d4d0c5b4d279bfe3585fbd806efefd3e51c82afa ] + +The Gemini ethernet controller provides hardware checksumming +for frames up to 1514 bytes including ethernet headers but not +FCS. + +If we start sending bigger frames (after first bumping up the MTU +on both interfaces sending and receiving the frames), truncated +packets start to appear on the target such as in this tcpdump +resulting from ping -s 1474: + +23:34:17.241983 14:d6:4d:a8:3c:4f (oui Unknown) > bc:ae:c5:6b:a8:3d (oui Unknown), +ethertype IPv4 (0x0800), length 1514: truncated-ip - 2 bytes missing! +(tos 0x0, ttl 64, id 32653, offset 0, flags [DF], proto ICMP (1), length 1502) +OpenWrt.lan > Fecusia: ICMP echo request, id 1672, seq 50, length 1482 + +If we bypass the hardware checksumming and provide a software +fallback, everything starts working fine up to the max TX MTU +of 2047 bytes, for example ping -s2000 192.168.1.2: + +00:44:29.587598 bc:ae:c5:6b:a8:3d (oui Unknown) > 14:d6:4d:a8:3c:4f (oui Unknown), +ethertype IPv4 (0x0800), length 2042: +(tos 0x0, ttl 64, id 51828, offset 0, flags [none], proto ICMP (1), length 2028) +Fecusia > OpenWrt.lan: ICMP echo reply, id 1683, seq 4, length 2008 + +The bit enabling to bypass hardware checksum (or any of the +"TSS" bits) are undocumented in the hardware reference manual. +The entire hardware checksum unit appears undocumented. The +conclusion that we need to use the "bypass" bit was found by +trial-and-error. + +Since no hardware checksum will happen, we slot in a software +checksum fallback. + +Check for the condition where we need to compute checksum on the +skb with either hardware or software using == CHECKSUM_PARTIAL instead +of != CHECKSUM_NONE which is an incomplete check according to +. + +On the D-Link DIR-685 router this fixes a bug on the conduit +interface to the RTL8366RB DSA switch: as the switch needs to add +space for its tag it increases the MTU on the conduit interface +to 1504 and that means that when the router sends packages +of 1500 bytes these get an extra 4 bytes of DSA tag and the +transfer fails because of the erroneous hardware checksumming, +affecting such basic functionality as the LuCI web interface. + +Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet") +Signed-off-by: Linus Walleij +Reviewed-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20231109-gemini-largeframe-fix-v4-2-6e611528db08@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cortina/gemini.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c +index 9fe8d22a26719..a2d4ace01ed3c 100644 +--- a/drivers/net/ethernet/cortina/gemini.c ++++ b/drivers/net/ethernet/cortina/gemini.c +@@ -1145,6 +1145,7 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, + dma_addr_t mapping; + unsigned short mtu; + void *buffer; ++ int ret; + + mtu = ETH_HLEN; + mtu += netdev->mtu; +@@ -1159,9 +1160,30 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, + word3 |= mtu; + } + +- if (skb->ip_summed != CHECKSUM_NONE) { ++ if (skb->len >= ETH_FRAME_LEN) { ++ /* Hardware offloaded checksumming isn't working on frames ++ * bigger than 1514 bytes. A hypothesis about this is that the ++ * checksum buffer is only 1518 bytes, so when the frames get ++ * bigger they get truncated, or the last few bytes get ++ * overwritten by the FCS. ++ * ++ * Just use software checksumming and bypass on bigger frames. ++ */ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ ret = skb_checksum_help(skb); ++ if (ret) ++ return ret; ++ } ++ word1 |= TSS_BYPASS_BIT; ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + int tcp = 0; + ++ /* We do not switch off the checksumming on non TCP/UDP ++ * frames: as is shown from tests, the checksumming engine ++ * is smart enough to see that a frame is not actually TCP ++ * or UDP and then just pass it through without any changes ++ * to the frame. ++ */ + if (skb->protocol == htons(ETH_P_IP)) { + word1 |= TSS_IP_CHKSUM_BIT; + tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch b/queue-6.5/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch new file mode 100644 index 00000000000..bc76563b9c0 --- /dev/null +++ b/queue-6.5/net-hns3-add-barrier-in-vf-mailbox-reply-process.patch @@ -0,0 +1,51 @@ +From 590885d4ec21be54d84ef69a5a50fa206e93137d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:08 +0800 +Subject: net: hns3: add barrier in vf mailbox reply process + +From: Yonglong Liu + +[ Upstream commit ac92c0a9a0603fb448e60f38e63302e4eebb8035 ] + +In hclgevf_mbx_handler() and hclgevf_get_mbx_resp() functions, +there is a typical store-store and load-load scenario between +received_resp and additional_info. This patch adds barrier +to fix the problem. + +Fixes: 4671042f1ef0 ("net: hns3: add match_id to check mailbox response from PF to VF") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +index bbf7b14079de3..85c2a634c8f96 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +@@ -63,6 +63,9 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, + i++; + } + ++ /* ensure additional_info will be seen after received_resp */ ++ smp_rmb(); ++ + if (i >= HCLGEVF_MAX_TRY_TIMES) { + dev_err(&hdev->pdev->dev, + "VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n", +@@ -178,6 +181,10 @@ static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev, + resp->resp_status = hclgevf_resp_to_errno(resp_status); + memcpy(resp->additional_info, req->msg.resp_data, + HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8)); ++ ++ /* ensure additional_info will be seen before setting received_resp */ ++ smp_wmb(); ++ + if (match_id) { + /* If match_id is not zero, it means PF support match_id. + * if the match_id is right, VF get the right response, or +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-fix-add-vlan-fail-issue.patch b/queue-6.5/net-hns3-fix-add-vlan-fail-issue.patch new file mode 100644 index 00000000000..d40a6f05a06 --- /dev/null +++ b/queue-6.5/net-hns3-fix-add-vlan-fail-issue.patch @@ -0,0 +1,192 @@ +From 755b7d0074cd0bd28e6dc1e505a91c7c3a3ca53f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:07 +0800 +Subject: net: hns3: fix add VLAN fail issue +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jian Shen + +[ Upstream commit 472a2ff63efb30234cbf6b2cdaf8117f21b4f8bc ] + +The hclge_sync_vlan_filter is called in periodic task, +trying to remove VLAN from vlan_del_fail_bmap. It can +be concurrence with VLAN adding operation from user. +So once user failed to delete a VLAN id, and add it +again soon, it may be removed by the periodic task, +which may cause the software configuration being +inconsistent with hardware. So add mutex handling +to avoid this. + + user hns3 driver + + periodic task + │ + add vlan 10 ───── hns3_vlan_rx_add_vid │ + │ (suppose success) │ + │ │ + del vlan 10 ───── hns3_vlan_rx_kill_vid │ + │ (suppose fail,add to │ + │ vlan_del_fail_bmap) │ + │ │ + add vlan 10 ───── hns3_vlan_rx_add_vid │ + (suppose success) │ + foreach vlan_del_fail_bmp + del vlan 10 + +Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../hisilicon/hns3/hns3pf/hclge_main.c | 28 +++++++++++++------ + .../hisilicon/hns3/hns3vf/hclgevf_main.c | 11 ++++++-- + 2 files changed, 29 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index ed6cf59853bf6..71154c0976aff 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -10026,8 +10026,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, + struct hclge_vport_vlan_cfg *vlan, *tmp; + struct hclge_dev *hdev = vport->back; + +- mutex_lock(&hdev->vport_lock); +- + list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { + if (vlan->vlan_id == vlan_id) { + if (is_write_tbl && vlan->hd_tbl_status) +@@ -10042,8 +10040,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, + break; + } + } +- +- mutex_unlock(&hdev->vport_lock); + } + + void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list) +@@ -10452,11 +10448,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, + * handle mailbox. Just record the vlan id, and remove it after + * reset finished. + */ ++ mutex_lock(&hdev->vport_lock); + if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || + test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) { + set_bit(vlan_id, vport->vlan_del_fail_bmap); ++ mutex_unlock(&hdev->vport_lock); + return -EBUSY; ++ } else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) { ++ clear_bit(vlan_id, vport->vlan_del_fail_bmap); + } ++ mutex_unlock(&hdev->vport_lock); + + /* when port base vlan enabled, we use port base vlan as the vlan + * filter entry. In this case, we don't update vlan filter table +@@ -10471,17 +10472,22 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, + } + + if (!ret) { +- if (!is_kill) ++ if (!is_kill) { + hclge_add_vport_vlan_table(vport, vlan_id, + writen_to_tbl); +- else if (is_kill && vlan_id != 0) ++ } else if (is_kill && vlan_id != 0) { ++ mutex_lock(&hdev->vport_lock); + hclge_rm_vport_vlan_table(vport, vlan_id, false); ++ mutex_unlock(&hdev->vport_lock); ++ } + } else if (is_kill) { + /* when remove hw vlan filter failed, record the vlan id, + * and try to remove it from hw later, to be consistence + * with stack + */ ++ mutex_lock(&hdev->vport_lock); + set_bit(vlan_id, vport->vlan_del_fail_bmap); ++ mutex_unlock(&hdev->vport_lock); + } + + hclge_set_vport_vlan_fltr_change(vport); +@@ -10521,6 +10527,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) + int i, ret, sync_cnt = 0; + u16 vlan_id; + ++ mutex_lock(&hdev->vport_lock); + /* start from vport 1 for PF is always alive */ + for (i = 0; i < hdev->num_alloc_vport; i++) { + struct hclge_vport *vport = &hdev->vport[i]; +@@ -10531,21 +10538,26 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) + ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), + vport->vport_id, vlan_id, + true); +- if (ret && ret != -EINVAL) ++ if (ret && ret != -EINVAL) { ++ mutex_unlock(&hdev->vport_lock); + return; ++ } + + clear_bit(vlan_id, vport->vlan_del_fail_bmap); + hclge_rm_vport_vlan_table(vport, vlan_id, false); + hclge_set_vport_vlan_fltr_change(vport); + + sync_cnt++; +- if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) ++ if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) { ++ mutex_unlock(&hdev->vport_lock); + return; ++ } + + vlan_id = find_first_bit(vport->vlan_del_fail_bmap, + VLAN_N_VID); + } + } ++ mutex_unlock(&hdev->vport_lock); + + hclge_sync_vlan_fltr_state(hdev); + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index a4d68fb216fb9..1c62e58ff6d89 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -1206,6 +1206,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, + test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) { + set_bit(vlan_id, hdev->vlan_del_fail_bmap); + return -EBUSY; ++ } else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) { ++ clear_bit(vlan_id, hdev->vlan_del_fail_bmap); + } + + hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, +@@ -1233,20 +1235,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) + int ret, sync_cnt = 0; + u16 vlan_id; + ++ if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID)) ++ return; ++ ++ rtnl_lock(); + vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); + while (vlan_id != VLAN_N_VID) { + ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q), + vlan_id, true); + if (ret) +- return; ++ break; + + clear_bit(vlan_id, hdev->vlan_del_fail_bmap); + sync_cnt++; + if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT) +- return; ++ break; + + vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); + } ++ rtnl_unlock(); + } + + static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-fix-incorrect-capability-bit-display-for-co.patch b/queue-6.5/net-hns3-fix-incorrect-capability-bit-display-for-co.patch new file mode 100644 index 00000000000..5601dad1f25 --- /dev/null +++ b/queue-6.5/net-hns3-fix-incorrect-capability-bit-display-for-co.patch @@ -0,0 +1,38 @@ +From 80ad2dc9f142c53d11ab4f9261c6bd9ce264e7a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:09 +0800 +Subject: net: hns3: fix incorrect capability bit display for copper port + +From: Jian Shen + +[ Upstream commit 75b247b57d8b71bcb679e4cb37d0db104848806c ] + +Currently, the FEC capability bit is default set for device version V2. +It's incorrect for the copper port. Eventhough it doesn't make the nic +work abnormal, but the capability information display in debugfs may +confuse user. So clear it when driver get the port type inforamtion. + +Fixes: 433ccce83504 ("net: hns3: use FEC capability queried from firmware") +Signed-off-by: Jian Shen +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 71154c0976aff..dd2baa05adba0 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -11664,6 +11664,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) + goto err_msi_irq_uninit; + + if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) { ++ clear_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); + if (hnae3_dev_phy_imp_supported(hdev)) + ret = hclge_update_tp_port_info(hdev); + else +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-fix-out-of-bounds-access-may-occur-when-coa.patch b/queue-6.5/net-hns3-fix-out-of-bounds-access-may-occur-when-coa.patch new file mode 100644 index 00000000000..e2678092a6c --- /dev/null +++ b/queue-6.5/net-hns3-fix-out-of-bounds-access-may-occur-when-coa.patch @@ -0,0 +1,49 @@ +From 6a8330ffe22c946c22a1fa12a7a676836cee77e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:10 +0800 +Subject: net: hns3: fix out-of-bounds access may occur when coalesce info is + read via debugfs + +From: Yonglong Liu + +[ Upstream commit 53aba458f23846112c0d44239580ff59bc5c36c3 ] + +The hns3 driver define an array of string to show the coalesce +info, but if the kernel adds a new mode or a new state, +out-of-bounds access may occur when coalesce info is read via +debugfs, this patch fix the problem. + +Fixes: c99fead7cb07 ("net: hns3: add debugfs support for interrupt coalesce") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +index 26fb6fefcb9d9..5d1814ed51427 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +@@ -500,11 +500,14 @@ static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector, + } + + sprintf(result[j++], "%d", i); +- sprintf(result[j++], "%s", dim_state_str[dim->state]); ++ sprintf(result[j++], "%s", dim->state < ARRAY_SIZE(dim_state_str) ? ++ dim_state_str[dim->state] : "unknown"); + sprintf(result[j++], "%u", dim->profile_ix); +- sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]); ++ sprintf(result[j++], "%s", dim->mode < ARRAY_SIZE(dim_cqe_mode_str) ? ++ dim_cqe_mode_str[dim->mode] : "unknown"); + sprintf(result[j++], "%s", +- dim_tune_stat_str[dim->tune_state]); ++ dim->tune_state < ARRAY_SIZE(dim_tune_stat_str) ? ++ dim_tune_stat_str[dim->tune_state] : "unknown"); + sprintf(result[j++], "%u", dim->steps_left); + sprintf(result[j++], "%u", dim->steps_right); + sprintf(result[j++], "%u", dim->tired); +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-fix-variable-may-not-initialized-problem-in.patch b/queue-6.5/net-hns3-fix-variable-may-not-initialized-problem-in.patch new file mode 100644 index 00000000000..94705993bf3 --- /dev/null +++ b/queue-6.5/net-hns3-fix-variable-may-not-initialized-problem-in.patch @@ -0,0 +1,38 @@ +From a02d4e65dd353e602d9be77274bbe518698434bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:11 +0800 +Subject: net: hns3: fix variable may not initialized problem in + hns3_init_mac_addr() + +From: Yonglong Liu + +[ Upstream commit dbd2f3b20c6ae425665b6975d766e3653d453e73 ] + +When a VF is calling hns3_init_mac_addr(), get_mac_addr() may +return fail, then the value of mac_addr_temp is not initialized. + +Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") +Signed-off-by: Yonglong Liu +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 71a2ec03f2b38..f644210afb70a 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -5139,7 +5139,7 @@ static int hns3_init_mac_addr(struct net_device *netdev) + struct hns3_nic_priv *priv = netdev_priv(netdev); + char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN]; + struct hnae3_handle *h = priv->ae_handle; +- u8 mac_addr_temp[ETH_ALEN]; ++ u8 mac_addr_temp[ETH_ALEN] = {0}; + int ret = 0; + + if (h->ae_algo->ops->get_mac_addr) +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-fix-vf-reset-fail-issue.patch b/queue-6.5/net-hns3-fix-vf-reset-fail-issue.patch new file mode 100644 index 00000000000..1770f08f665 --- /dev/null +++ b/queue-6.5/net-hns3-fix-vf-reset-fail-issue.patch @@ -0,0 +1,83 @@ +From 6f7af0ff8dd8535532b2e3623795d4bac3bfc8b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:12 +0800 +Subject: net: hns3: fix VF reset fail issue + +From: Jijie Shao + +[ Upstream commit 65e98bb56fa3ce2edb400930c05238c9b380500e ] + +Currently the reset process in hns3 and firmware watchdog init process is +asynchronous. We think firmware watchdog initialization is completed +before VF clear the interrupt source. However, firmware initialization +may not complete early. So VF will receive multiple reset interrupts +and fail to reset. + +So we add delay before VF interrupt source and 5 ms delay +is enough to avoid second reset interrupt. + +Fixes: 427900d27d86 ("net: hns3: fix the timing issue of VF clearing interrupt sources") +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 14 +++++++++++++- + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 1 + + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 1c62e58ff6d89..0aa9beefd1c7e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -1981,8 +1981,18 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, + return HCLGEVF_VECTOR0_EVENT_OTHER; + } + ++static void hclgevf_reset_timer(struct timer_list *t) ++{ ++ struct hclgevf_dev *hdev = from_timer(hdev, t, reset_timer); ++ ++ hclgevf_clear_event_cause(hdev, HCLGEVF_VECTOR0_EVENT_RST); ++ hclgevf_reset_task_schedule(hdev); ++} ++ + static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) + { ++#define HCLGEVF_RESET_DELAY 5 ++ + enum hclgevf_evt_cause event_cause; + struct hclgevf_dev *hdev = data; + u32 clearval; +@@ -1994,7 +2004,8 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) + + switch (event_cause) { + case HCLGEVF_VECTOR0_EVENT_RST: +- hclgevf_reset_task_schedule(hdev); ++ mod_timer(&hdev->reset_timer, ++ jiffies + msecs_to_jiffies(HCLGEVF_RESET_DELAY)); + break; + case HCLGEVF_VECTOR0_EVENT_MBX: + hclgevf_mbx_handler(hdev); +@@ -2937,6 +2948,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) + HCLGEVF_DRIVER_NAME); + + hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); ++ timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); + + return 0; + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +index 81c16b8c8da29..a73f2bf3a56a6 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +@@ -219,6 +219,7 @@ struct hclgevf_dev { + enum hnae3_reset_type reset_level; + unsigned long reset_pending; + enum hnae3_reset_type reset_type; ++ struct timer_list reset_timer; + + #define HCLGEVF_RESET_REQUESTED 0 + #define HCLGEVF_RESET_PENDING 1 +-- +2.42.0 + diff --git a/queue-6.5/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch b/queue-6.5/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch new file mode 100644 index 00000000000..209361bf405 --- /dev/null +++ b/queue-6.5/net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch @@ -0,0 +1,57 @@ +From 9ea8a41a2a614625e9b20ff7ec7a8004e2de0835 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Nov 2023 17:37:13 +0800 +Subject: net: hns3: fix VF wrong speed and duplex issue + +From: Jijie Shao + +[ Upstream commit dff655e82faffc287d4a72a59f66fa120bf904e4 ] + +If PF is down, firmware will returns 10 Mbit/s rate and half-duplex mode +when PF queries the port information from firmware. + +After imp reset command is executed, PF status changes to down, +and PF will query link status and updates port information +from firmware in a periodic scheduled task. + +However, there is a low probability that port information is updated +when PF is down, and then PF link status changes to up. +In this case, PF synchronizes incorrect rate and duplex mode to VF. + +This patch fixes it by updating port information before +PF synchronizes the rate and duplex to the VF +when PF changes to up. + +Fixes: 18b6e31f8bf4 ("net: hns3: PF add support for pushing link status to VFs") +Signed-off-by: Jijie Shao +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index dd2baa05adba0..0f868605300a2 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -61,6 +61,7 @@ static void hclge_sync_fd_table(struct hclge_dev *hdev); + static void hclge_update_fec_stats(struct hclge_dev *hdev); + static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, + int wait_cnt); ++static int hclge_update_port_info(struct hclge_dev *hdev); + + static struct hnae3_ae_algo ae_algo; + +@@ -3043,6 +3044,9 @@ static void hclge_update_link_status(struct hclge_dev *hdev) + + if (state != hdev->hw.mac.link) { + hdev->hw.mac.link = state; ++ if (state == HCLGE_LINK_STATUS_UP) ++ hclge_update_port_info(hdev); ++ + client->ops->link_status_change(handle, state); + hclge_config_mac_tnl_int(hdev, state); + if (rclient && rclient->ops->link_status_change) +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5-consolidate-devlink-documentation-in-devlin.patch b/queue-6.5/net-mlx5-consolidate-devlink-documentation-in-devlin.patch new file mode 100644 index 00000000000..2ed6c21dc1d --- /dev/null +++ b/queue-6.5/net-mlx5-consolidate-devlink-documentation-in-devlin.patch @@ -0,0 +1,570 @@ +From 6c685584106cc705c4f049f048ce50974bc4ddc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 13:57:00 -0800 +Subject: net/mlx5: Consolidate devlink documentation in devlink/mlx5.rst + +From: Rahul Rameshbabu + +[ Upstream commit b608dd670bb69c89d5074685899d4c1089f57a16 ] + +De-duplicate documentation by removing mellanox/mlx5/devlink.rst. Instead, +only use the generic devlink documentation directory to document mlx5 +devlink parameters. Avoid providing general devlink tool usage information +in mlx5-specific documentation. + +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Jiri Pirko +Reviewed-by: Gal Pressman +Signed-off-by: Saeed Mahameed +Stable-dep-of: 92214be5979c ("net/mlx5e: Update doorbell for port timestamping CQ before the software counter") +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/devlink.rst | 313 ------------------ + .../ethernet/mellanox/mlx5/index.rst | 1 - + Documentation/networking/devlink/mlx5.rst | 179 ++++++++++ + 3 files changed, 179 insertions(+), 314 deletions(-) + delete mode 100644 Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst + +diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst +deleted file mode 100644 +index a4edf908b707c..0000000000000 +--- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst ++++ /dev/null +@@ -1,313 +0,0 @@ +-.. SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +-.. include:: +- +-======= +-Devlink +-======= +- +-:Copyright: |copy| 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +- +-Contents +-======== +- +-- `Info`_ +-- `Parameters`_ +-- `Health reporters`_ +- +-Info +-==== +- +-The devlink info reports the running and stored firmware versions on device. +-It also prints the device PSID which represents the HCA board type ID. +- +-User command example:: +- +- $ devlink dev info pci/0000:00:06.0 +- pci/0000:00:06.0: +- driver mlx5_core +- versions: +- fixed: +- fw.psid MT_0000000009 +- running: +- fw.version 16.26.0100 +- stored: +- fw.version 16.26.0100 +- +-Parameters +-========== +- +-flow_steering_mode: Device flow steering mode +---------------------------------------------- +-The flow steering mode parameter controls the flow steering mode of the driver. +-Two modes are supported: +- +-1. 'dmfs' - Device managed flow steering. +-2. 'smfs' - Software/Driver managed flow steering. +- +-In DMFS mode, the HW steering entities are created and managed through the +-Firmware. +-In SMFS mode, the HW steering entities are created and managed though by +-the driver directly into hardware without firmware intervention. +- +-SMFS mode is faster and provides better rule insertion rate compared to default DMFS mode. +- +-User command examples: +- +-- Set SMFS flow steering mode:: +- +- $ devlink dev param set pci/0000:06:00.0 name flow_steering_mode value "smfs" cmode runtime +- +-- Read device flow steering mode:: +- +- $ devlink dev param show pci/0000:06:00.0 name flow_steering_mode +- pci/0000:06:00.0: +- name flow_steering_mode type driver-specific +- values: +- cmode runtime value smfs +- +-enable_roce: RoCE enablement state +----------------------------------- +-If the device supports RoCE disablement, RoCE enablement state controls device +-support for RoCE capability. Otherwise, the control occurs in the driver stack. +-When RoCE is disabled at the driver level, only raw ethernet QPs are supported. +- +-To change RoCE enablement state, a user must change the driverinit cmode value +-and run devlink reload. +- +-User command examples: +- +-- Disable RoCE:: +- +- $ devlink dev param set pci/0000:06:00.0 name enable_roce value false cmode driverinit +- $ devlink dev reload pci/0000:06:00.0 +- +-- Read RoCE enablement state:: +- +- $ devlink dev param show pci/0000:06:00.0 name enable_roce +- pci/0000:06:00.0: +- name enable_roce type generic +- values: +- cmode driverinit value true +- +-esw_port_metadata: Eswitch port metadata state +----------------------------------------------- +-When applicable, disabling eswitch metadata can increase packet rate +-up to 20% depending on the use case and packet sizes. +- +-Eswitch port metadata state controls whether to internally tag packets with +-metadata. Metadata tagging must be enabled for multi-port RoCE, failover +-between representors and stacked devices. +-By default metadata is enabled on the supported devices in E-switch. +-Metadata is applicable only for E-switch in switchdev mode and +-users may disable it when NONE of the below use cases will be in use: +- +-1. HCA is in Dual/multi-port RoCE mode. +-2. VF/SF representor bonding (Usually used for Live migration) +-3. Stacked devices +- +-When metadata is disabled, the above use cases will fail to initialize if +-users try to enable them. +- +-- Show eswitch port metadata:: +- +- $ devlink dev param show pci/0000:06:00.0 name esw_port_metadata +- pci/0000:06:00.0: +- name esw_port_metadata type driver-specific +- values: +- cmode runtime value true +- +-- Disable eswitch port metadata:: +- +- $ devlink dev param set pci/0000:06:00.0 name esw_port_metadata value false cmode runtime +- +-- Change eswitch mode to switchdev mode where after choosing the metadata value:: +- +- $ devlink dev eswitch set pci/0000:06:00.0 mode switchdev +- +-hairpin_num_queues: Number of hairpin queues +--------------------------------------------- +-We refer to a TC NIC rule that involves forwarding as "hairpin". +- +-Hairpin queues are mlx5 hardware specific implementation for hardware +-forwarding of such packets. +- +-- Show the number of hairpin queues:: +- +- $ devlink dev param show pci/0000:06:00.0 name hairpin_num_queues +- pci/0000:06:00.0: +- name hairpin_num_queues type driver-specific +- values: +- cmode driverinit value 2 +- +-- Change the number of hairpin queues:: +- +- $ devlink dev param set pci/0000:06:00.0 name hairpin_num_queues value 4 cmode driverinit +- +-hairpin_queue_size: Size of the hairpin queues +----------------------------------------------- +-Control the size of the hairpin queues. +- +-- Show the size of the hairpin queues:: +- +- $ devlink dev param show pci/0000:06:00.0 name hairpin_queue_size +- pci/0000:06:00.0: +- name hairpin_queue_size type driver-specific +- values: +- cmode driverinit value 1024 +- +-- Change the size (in packets) of the hairpin queues:: +- +- $ devlink dev param set pci/0000:06:00.0 name hairpin_queue_size value 512 cmode driverinit +- +-Health reporters +-================ +- +-tx reporter +------------ +-The tx reporter is responsible for reporting and recovering of the following two error scenarios: +- +-- tx timeout +- Report on kernel tx timeout detection. +- Recover by searching lost interrupts. +-- tx error completion +- Report on error tx completion. +- Recover by flushing the tx queue and reset it. +- +-tx reporter also support on demand diagnose callback, on which it provides +-real time information of its send queues status. +- +-User commands examples: +- +-- Diagnose send queues status:: +- +- $ devlink health diagnose pci/0000:82:00.0 reporter tx +- +-.. note:: +- This command has valid output only when interface is up, otherwise the command has empty output. +- +-- Show number of tx errors indicated, number of recover flows ended successfully, +- is autorecover enabled and graceful period from last recover:: +- +- $ devlink health show pci/0000:82:00.0 reporter tx +- +-rx reporter +------------ +-The rx reporter is responsible for reporting and recovering of the following two error scenarios: +- +-- rx queues' initialization (population) timeout +- Population of rx queues' descriptors on ring initialization is done +- in napi context via triggering an irq. In case of a failure to get +- the minimum amount of descriptors, a timeout would occur, and +- descriptors could be recovered by polling the EQ (Event Queue). +-- rx completions with errors (reported by HW on interrupt context) +- Report on rx completion error. +- Recover (if needed) by flushing the related queue and reset it. +- +-rx reporter also supports on demand diagnose callback, on which it +-provides real time information of its receive queues' status. +- +-- Diagnose rx queues' status and corresponding completion queue:: +- +- $ devlink health diagnose pci/0000:82:00.0 reporter rx +- +-NOTE: This command has valid output only when interface is up. Otherwise, the command has empty output. +- +-- Show number of rx errors indicated, number of recover flows ended successfully, +- is autorecover enabled, and graceful period from last recover:: +- +- $ devlink health show pci/0000:82:00.0 reporter rx +- +-fw reporter +------------ +-The fw reporter implements `diagnose` and `dump` callbacks. +-It follows symptoms of fw error such as fw syndrome by triggering +-fw core dump and storing it into the dump buffer. +-The fw reporter diagnose command can be triggered any time by the user to check +-current fw status. +- +-User commands examples: +- +-- Check fw heath status:: +- +- $ devlink health diagnose pci/0000:82:00.0 reporter fw +- +-- Read FW core dump if already stored or trigger new one:: +- +- $ devlink health dump show pci/0000:82:00.0 reporter fw +- +-.. note:: +- This command can run only on the PF which has fw tracer ownership, +- running it on other PF or any VF will return "Operation not permitted". +- +-fw fatal reporter +------------------ +-The fw fatal reporter implements `dump` and `recover` callbacks. +-It follows fatal errors indications by CR-space dump and recover flow. +-The CR-space dump uses vsc interface which is valid even if the FW command +-interface is not functional, which is the case in most FW fatal errors. +-The recover function runs recover flow which reloads the driver and triggers fw +-reset if needed. +-On firmware error, the health buffer is dumped into the dmesg. The log +-level is derived from the error's severity (given in health buffer). +- +-User commands examples: +- +-- Run fw recover flow manually:: +- +- $ devlink health recover pci/0000:82:00.0 reporter fw_fatal +- +-- Read FW CR-space dump if already stored or trigger new one:: +- +- $ devlink health dump show pci/0000:82:00.1 reporter fw_fatal +- +-.. note:: +- This command can run only on PF. +- +-vnic reporter +-------------- +-The vnic reporter implements only the `diagnose` callback. +-It is responsible for querying the vnic diagnostic counters from fw and displaying +-them in realtime. +- +-Description of the vnic counters: +- +-- total_q_under_processor_handle +- number of queues in an error state due to +- an async error or errored command. +-- send_queue_priority_update_flow +- number of QP/SQ priority/SL update events. +-- cq_overrun +- number of times CQ entered an error state due to an overflow. +-- async_eq_overrun +- number of times an EQ mapped to async events was overrun. +- comp_eq_overrun number of times an EQ mapped to completion events was +- overrun. +-- quota_exceeded_command +- number of commands issued and failed due to quota exceeded. +-- invalid_command +- number of commands issued and failed dues to any reason other than quota +- exceeded. +-- nic_receive_steering_discard +- number of packets that completed RX flow +- steering but were discarded due to a mismatch in flow table. +-- generated_pkt_steering_fail +- number of packets generated by the VNIC experiencing unexpected steering +- failure (at any point in steering flow). +-- handled_pkt_steering_fail +- number of packets handled by the VNIC experiencing unexpected steering +- failure (at any point in steering flow owned by the VNIC, including the FDB +- for the eswitch owner). +- +-User commands examples: +- +-- Diagnose PF/VF vnic counters:: +- +- $ devlink health diagnose pci/0000:82:00.1 reporter vnic +- +-- Diagnose representor vnic counters (performed by supplying devlink port of the +- representor, which can be obtained via devlink port command):: +- +- $ devlink health diagnose pci/0000:82:00.1/65537 reporter vnic +- +-.. note:: +- This command can run over all interfaces such as PF/VF and representor ports. +diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/index.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/index.rst +index 3fdcd6b61ccfa..581a91caa5795 100644 +--- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/index.rst ++++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/index.rst +@@ -13,7 +13,6 @@ Contents: + :maxdepth: 2 + + kconfig +- devlink + switchdev + tracepoints + counters +diff --git a/Documentation/networking/devlink/mlx5.rst b/Documentation/networking/devlink/mlx5.rst +index 202798d6501e7..196a4bb28df1e 100644 +--- a/Documentation/networking/devlink/mlx5.rst ++++ b/Documentation/networking/devlink/mlx5.rst +@@ -18,6 +18,11 @@ Parameters + * - ``enable_roce`` + - driverinit + - Type: Boolean ++ ++ If the device supports RoCE disablement, RoCE enablement state controls ++ device support for RoCE capability. Otherwise, the control occurs in the ++ driver stack. When RoCE is disabled at the driver level, only raw ++ ethernet QPs are supported. + * - ``io_eq_size`` + - driverinit + - The range is between 64 and 4096. +@@ -48,6 +53,9 @@ parameters. + * ``smfs`` Software managed flow steering. In SMFS mode, the HW + steering entities are created and manage through the driver without + firmware intervention. ++ ++ SMFS mode is faster and provides better rule insertion rate compared to ++ default DMFS mode. + * - ``fdb_large_groups`` + - u32 + - driverinit +@@ -71,7 +79,24 @@ parameters. + deprecated. + + Default: disabled ++ * - ``esw_port_metadata`` ++ - Boolean ++ - runtime ++ - When applicable, disabling eswitch metadata can increase packet rate up ++ to 20% depending on the use case and packet sizes. ++ ++ Eswitch port metadata state controls whether to internally tag packets ++ with metadata. Metadata tagging must be enabled for multi-port RoCE, ++ failover between representors and stacked devices. By default metadata is ++ enabled on the supported devices in E-switch. Metadata is applicable only ++ for E-switch in switchdev mode and users may disable it when NONE of the ++ below use cases will be in use: ++ 1. HCA is in Dual/multi-port RoCE mode. ++ 2. VF/SF representor bonding (Usually used for Live migration) ++ 3. Stacked devices + ++ When metadata is disabled, the above use cases will fail to initialize if ++ users try to enable them. + * - ``hairpin_num_queues`` + - u32 + - driverinit +@@ -104,3 +129,157 @@ The ``mlx5`` driver reports the following versions + * - ``fw.version`` + - stored, running + - Three digit major.minor.subminor firmware version number. ++ ++Health reporters ++================ ++ ++tx reporter ++----------- ++The tx reporter is responsible for reporting and recovering of the following two error scenarios: ++ ++- tx timeout ++ Report on kernel tx timeout detection. ++ Recover by searching lost interrupts. ++- tx error completion ++ Report on error tx completion. ++ Recover by flushing the tx queue and reset it. ++ ++tx reporter also support on demand diagnose callback, on which it provides ++real time information of its send queues status. ++ ++User commands examples: ++ ++- Diagnose send queues status:: ++ ++ $ devlink health diagnose pci/0000:82:00.0 reporter tx ++ ++.. note:: ++ This command has valid output only when interface is up, otherwise the command has empty output. ++ ++- Show number of tx errors indicated, number of recover flows ended successfully, ++ is autorecover enabled and graceful period from last recover:: ++ ++ $ devlink health show pci/0000:82:00.0 reporter tx ++ ++rx reporter ++----------- ++The rx reporter is responsible for reporting and recovering of the following two error scenarios: ++ ++- rx queues' initialization (population) timeout ++ Population of rx queues' descriptors on ring initialization is done ++ in napi context via triggering an irq. In case of a failure to get ++ the minimum amount of descriptors, a timeout would occur, and ++ descriptors could be recovered by polling the EQ (Event Queue). ++- rx completions with errors (reported by HW on interrupt context) ++ Report on rx completion error. ++ Recover (if needed) by flushing the related queue and reset it. ++ ++rx reporter also supports on demand diagnose callback, on which it ++provides real time information of its receive queues' status. ++ ++- Diagnose rx queues' status and corresponding completion queue:: ++ ++ $ devlink health diagnose pci/0000:82:00.0 reporter rx ++ ++.. note:: ++ This command has valid output only when interface is up. Otherwise, the command has empty output. ++ ++- Show number of rx errors indicated, number of recover flows ended successfully, ++ is autorecover enabled, and graceful period from last recover:: ++ ++ $ devlink health show pci/0000:82:00.0 reporter rx ++ ++fw reporter ++----------- ++The fw reporter implements `diagnose` and `dump` callbacks. ++It follows symptoms of fw error such as fw syndrome by triggering ++fw core dump and storing it into the dump buffer. ++The fw reporter diagnose command can be triggered any time by the user to check ++current fw status. ++ ++User commands examples: ++ ++- Check fw heath status:: ++ ++ $ devlink health diagnose pci/0000:82:00.0 reporter fw ++ ++- Read FW core dump if already stored or trigger new one:: ++ ++ $ devlink health dump show pci/0000:82:00.0 reporter fw ++ ++.. note:: ++ This command can run only on the PF which has fw tracer ownership, ++ running it on other PF or any VF will return "Operation not permitted". ++ ++fw fatal reporter ++----------------- ++The fw fatal reporter implements `dump` and `recover` callbacks. ++It follows fatal errors indications by CR-space dump and recover flow. ++The CR-space dump uses vsc interface which is valid even if the FW command ++interface is not functional, which is the case in most FW fatal errors. ++The recover function runs recover flow which reloads the driver and triggers fw ++reset if needed. ++On firmware error, the health buffer is dumped into the dmesg. The log ++level is derived from the error's severity (given in health buffer). ++ ++User commands examples: ++ ++- Run fw recover flow manually:: ++ ++ $ devlink health recover pci/0000:82:00.0 reporter fw_fatal ++ ++- Read FW CR-space dump if already stored or trigger new one:: ++ ++ $ devlink health dump show pci/0000:82:00.1 reporter fw_fatal ++ ++.. note:: ++ This command can run only on PF. ++ ++vnic reporter ++------------- ++The vnic reporter implements only the `diagnose` callback. ++It is responsible for querying the vnic diagnostic counters from fw and displaying ++them in realtime. ++ ++Description of the vnic counters: ++ ++- total_q_under_processor_handle ++ number of queues in an error state due to ++ an async error or errored command. ++- send_queue_priority_update_flow ++ number of QP/SQ priority/SL update events. ++- cq_overrun ++ number of times CQ entered an error state due to an overflow. ++- async_eq_overrun ++ number of times an EQ mapped to async events was overrun. ++ comp_eq_overrun number of times an EQ mapped to completion events was ++ overrun. ++- quota_exceeded_command ++ number of commands issued and failed due to quota exceeded. ++- invalid_command ++ number of commands issued and failed dues to any reason other than quota ++ exceeded. ++- nic_receive_steering_discard ++ number of packets that completed RX flow ++ steering but were discarded due to a mismatch in flow table. ++- generated_pkt_steering_fail ++ number of packets generated by the VNIC experiencing unexpected steering ++ failure (at any point in steering flow). ++- handled_pkt_steering_fail ++ number of packets handled by the VNIC experiencing unexpected steering ++ failure (at any point in steering flow owned by the VNIC, including the FDB ++ for the eswitch owner). ++ ++User commands examples: ++ ++- Diagnose PF/VF vnic counters:: ++ ++ $ devlink health diagnose pci/0000:82:00.1 reporter vnic ++ ++- Diagnose representor vnic counters (performed by supplying devlink port of the ++ representor, which can be obtained via devlink port command):: ++ ++ $ devlink health diagnose pci/0000:82:00.1/65537 reporter vnic ++ ++.. note:: ++ This command can run over all interfaces such as PF/VF and representor ports. +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5-decouple-phc-.adjtime-and-.adjphase-impleme.patch b/queue-6.5/net-mlx5-decouple-phc-.adjtime-and-.adjphase-impleme.patch new file mode 100644 index 00000000000..70f271a31c1 --- /dev/null +++ b/queue-6.5/net-mlx5-decouple-phc-.adjtime-and-.adjphase-impleme.patch @@ -0,0 +1,46 @@ +From fd373190d4d0f1d27ac2a5eaa5c32e0bf9d17d24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:35 -0800 +Subject: net/mlx5: Decouple PHC .adjtime and .adjphase implementations + +From: Rahul Rameshbabu + +[ Upstream commit fd64fd13c49a53012ce9170449dcd9eb71c11284 ] + +When running a phase adjustment operation, the free running clock should +not be modified at all. The phase control keyword is intended to trigger an +internal servo on the device that will converge to the provided delta. A +free running counter cannot implement phase adjustment. + +Fixes: 8e11a68e2e8a ("net/mlx5: Add adjphase function to support hardware-only offset control") +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-5-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index aa29f09e83564..0c83ef174275a 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -384,7 +384,12 @@ static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) + + static int mlx5_ptp_adjphase(struct ptp_clock_info *ptp, s32 delta) + { +- return mlx5_ptp_adjtime(ptp, delta); ++ struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); ++ struct mlx5_core_dev *mdev; ++ ++ mdev = container_of(clock, struct mlx5_core_dev, clock); ++ ++ return mlx5_ptp_adjtime_real_time(mdev, delta); + } + + static int mlx5_ptp_freq_adj_real_time(struct mlx5_core_dev *mdev, long scaled_ppm) +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5-increase-size-of-irq-name-buffer.patch b/queue-6.5/net-mlx5-increase-size-of-irq-name-buffer.patch new file mode 100644 index 00000000000..a0e9f60869c --- /dev/null +++ b/queue-6.5/net-mlx5-increase-size-of-irq-name-buffer.patch @@ -0,0 +1,76 @@ +From b8ad0839fcbeb6413b71fc95fa1d391add6c9f22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:43 -0800 +Subject: net/mlx5: Increase size of irq name buffer + +From: Rahul Rameshbabu + +[ Upstream commit 3338bebfc26a1e2cebbba82a1cf12c0159608e73 ] + +Without increased buffer size, will trigger -Wformat-truncation with W=1 +for the snprintf operation writing to the buffer. + + drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c: In function 'mlx5_irq_alloc': + drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c:296:7: error: '@pci:' directive output may be truncated writing 5 bytes into a region of size between 1 and 32 [-Werror=format-truncation=] + 296 | "%s@pci:%s", name, pci_name(dev->pdev)); + | ^~~~~ + drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c:295:2: note: 'snprintf' output 6 or more bytes (assuming 37) into a destination of size 32 + 295 | snprintf(irq->name, MLX5_MAX_IRQ_NAME, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 296 | "%s@pci:%s", name, pci_name(dev->pdev)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: ada9f5d00797 ("IB/mlx5: Fix eq names to display nicely in /proc/interrupts") +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d4ab2e97dcfbcd748ae71761a9d8e5e41cc732c +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Dragos Tatulea +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-13-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 6 +++--- + drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h | 3 +++ + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +index cba2a4afb5fda..235e170c65bb7 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +@@ -28,7 +28,7 @@ + struct mlx5_irq { + struct atomic_notifier_head nh; + cpumask_var_t mask; +- char name[MLX5_MAX_IRQ_NAME]; ++ char name[MLX5_MAX_IRQ_FORMATTED_NAME]; + struct mlx5_irq_pool *pool; + int refcount; + struct msi_map map; +@@ -289,8 +289,8 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i, + else + irq_sf_set_name(pool, name, i); + ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh); +- snprintf(irq->name, MLX5_MAX_IRQ_NAME, +- "%s@pci:%s", name, pci_name(dev->pdev)); ++ snprintf(irq->name, MLX5_MAX_IRQ_FORMATTED_NAME, ++ MLX5_IRQ_NAME_FORMAT_STR, name, pci_name(dev->pdev)); + err = request_irq(irq->map.virq, irq_int_handler, 0, irq->name, + &irq->nh); + if (err) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h +index d3a77a0ab8488..c4d377f8df308 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h +@@ -7,6 +7,9 @@ + #include + + #define MLX5_MAX_IRQ_NAME (32) ++#define MLX5_IRQ_NAME_FORMAT_STR ("%s@pci:%s") ++#define MLX5_MAX_IRQ_FORMATTED_NAME \ ++ (MLX5_MAX_IRQ_NAME + sizeof(MLX5_IRQ_NAME_FORMAT_STR)) + /* max irq_index is 2047, so four chars */ + #define MLX5_MAX_IRQ_IDX_CHARS (4) + #define MLX5_EQ_REFS_PER_IRQ (2) +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-add-recovery-flow-for-tx-devlink-health-re.patch b/queue-6.5/net-mlx5e-add-recovery-flow-for-tx-devlink-health-re.patch new file mode 100644 index 00000000000..6e35c42d5ec --- /dev/null +++ b/queue-6.5/net-mlx5e-add-recovery-flow-for-tx-devlink-health-re.patch @@ -0,0 +1,249 @@ +From 3caf4c7ea6a68a6ad4f5c05fdaa47db54f088b71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Aug 2023 21:10:21 -0700 +Subject: net/mlx5e: Add recovery flow for tx devlink health reporter for + unhealthy PTP SQ + +From: Rahul Rameshbabu + +[ Upstream commit 53b836a44db4259b94ffcfff321fb3d63f976b76 ] + +A new check for the tx devlink health reporter is introduced for +determining when the PTP port timestamping SQ is considered unhealthy. If +there are enough CQEs considered never to be delivered, the space that can +be utilized on the SQ decreases significantly, impacting performance and +usability of the SQ. The health reporter is triggered when the number of +likely never delivered port timestamping CQEs that utilize the space of the +PTP SQ is greater than 93.75% of the total capacity of the SQ. A devlink +health reporter recover method is also provided for this specific TX error +context that restarts the PTP SQ. + +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Stable-dep-of: 92214be5979c ("net/mlx5e: Update doorbell for port timestamping CQ before the software counter") +Signed-off-by: Sasha Levin +--- + Documentation/networking/devlink/mlx5.rst | 5 +- + .../ethernet/mellanox/mlx5/core/en/health.h | 1 + + .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 22 +++++++ + .../net/ethernet/mellanox/mlx5/core/en/ptp.h | 2 + + .../mellanox/mlx5/core/en/reporter_tx.c | 65 +++++++++++++++++++ + 5 files changed, 94 insertions(+), 1 deletion(-) + +diff --git a/Documentation/networking/devlink/mlx5.rst b/Documentation/networking/devlink/mlx5.rst +index 196a4bb28df1e..702f204a3dbd3 100644 +--- a/Documentation/networking/devlink/mlx5.rst ++++ b/Documentation/networking/devlink/mlx5.rst +@@ -135,7 +135,7 @@ Health reporters + + tx reporter + ----------- +-The tx reporter is responsible for reporting and recovering of the following two error scenarios: ++The tx reporter is responsible for reporting and recovering of the following three error scenarios: + + - tx timeout + Report on kernel tx timeout detection. +@@ -143,6 +143,9 @@ The tx reporter is responsible for reporting and recovering of the following two + - tx error completion + Report on error tx completion. + Recover by flushing the tx queue and reset it. ++- tx PTP port timestamping CQ unhealthy ++ Report too many CQEs never delivered on port ts CQ. ++ Recover by flushing and re-creating all PTP channels. + + tx reporter also support on demand diagnose callback, on which it provides + real time information of its send queues status. +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/health.h b/drivers/net/ethernet/mellanox/mlx5/core/en/health.h +index 0107e4e73bb06..415840c3ef84f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/health.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/health.h +@@ -18,6 +18,7 @@ void mlx5e_reporter_tx_create(struct mlx5e_priv *priv); + void mlx5e_reporter_tx_destroy(struct mlx5e_priv *priv); + void mlx5e_reporter_tx_err_cqe(struct mlx5e_txqsq *sq); + int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq); ++void mlx5e_reporter_tx_ptpsq_unhealthy(struct mlx5e_ptpsq *ptpsq); + + int mlx5e_health_cq_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg); + int mlx5e_health_cq_common_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +index 8680d21f3e7b0..bb11e644d24f7 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +@@ -2,6 +2,7 @@ + // Copyright (c) 2020 Mellanox Technologies + + #include "en/ptp.h" ++#include "en/health.h" + #include "en/txrx.h" + #include "en/params.h" + #include "en/fs_tt_redirect.h" +@@ -140,6 +141,12 @@ mlx5e_ptp_metadata_map_remove(struct mlx5e_ptp_metadata_map *map, u16 metadata) + return skb; + } + ++static bool mlx5e_ptp_metadata_map_unhealthy(struct mlx5e_ptp_metadata_map *map) ++{ ++ /* Considered beginning unhealthy state if size * 15 / 2^4 cannot be reclaimed. */ ++ return map->undelivered_counter > (map->capacity >> 4) * 15; ++} ++ + static void mlx5e_ptpsq_mark_ts_cqes_undelivered(struct mlx5e_ptpsq *ptpsq, + ktime_t port_tstamp) + { +@@ -205,6 +212,9 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, + out: + napi_consume_skb(skb, budget); + mlx5e_ptp_metadata_fifo_push(&ptpsq->metadata_freelist, metadata_id); ++ if (unlikely(mlx5e_ptp_metadata_map_unhealthy(&ptpsq->metadata_map)) && ++ !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) ++ queue_work(ptpsq->txqsq.priv->wq, &ptpsq->report_unhealthy_work); + } + + static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) +@@ -422,6 +432,14 @@ static void mlx5e_ptp_free_traffic_db(struct mlx5e_ptpsq *ptpsq) + kvfree(ptpsq->ts_cqe_pending_list); + } + ++static void mlx5e_ptpsq_unhealthy_work(struct work_struct *work) ++{ ++ struct mlx5e_ptpsq *ptpsq = ++ container_of(work, struct mlx5e_ptpsq, report_unhealthy_work); ++ ++ mlx5e_reporter_tx_ptpsq_unhealthy(ptpsq); ++} ++ + static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, + int txq_ix, struct mlx5e_ptp_params *cparams, + int tc, struct mlx5e_ptpsq *ptpsq) +@@ -451,6 +469,8 @@ static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, + if (err) + goto err_free_txqsq; + ++ INIT_WORK(&ptpsq->report_unhealthy_work, mlx5e_ptpsq_unhealthy_work); ++ + return 0; + + err_free_txqsq: +@@ -464,6 +484,8 @@ static void mlx5e_ptp_close_txqsq(struct mlx5e_ptpsq *ptpsq) + struct mlx5e_txqsq *sq = &ptpsq->txqsq; + struct mlx5_core_dev *mdev = sq->mdev; + ++ if (current_work() != &ptpsq->report_unhealthy_work) ++ cancel_work_sync(&ptpsq->report_unhealthy_work); + mlx5e_ptp_free_traffic_db(ptpsq); + cancel_work_sync(&sq->recover_work); + mlx5e_ptp_destroy_sq(mdev, sq->sqn); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h +index 7c5597d4589df..7b700d0f956a8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #define MLX5E_PTP_CHANNEL_IX 0 + #define MLX5E_PTP_MAX_LOG_SQ_SIZE (8U) +@@ -34,6 +35,7 @@ struct mlx5e_ptpsq { + struct mlx5e_ptp_cq_stats *cq_stats; + u16 ts_cqe_ctr_mask; + ++ struct work_struct report_unhealthy_work; + struct mlx5e_ptp_port_ts_cqe_list *ts_cqe_pending_list; + struct mlx5e_ptp_metadata_fifo metadata_freelist; + struct mlx5e_ptp_metadata_map metadata_map; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +index b35ff289af492..ff8242f67c545 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +@@ -164,6 +164,43 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) + return err; + } + ++static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) ++{ ++ struct mlx5e_ptpsq *ptpsq = ctx; ++ struct mlx5e_channels *chs; ++ struct net_device *netdev; ++ struct mlx5e_priv *priv; ++ int carrier_ok; ++ int err; ++ ++ if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &ptpsq->txqsq.state)) ++ return 0; ++ ++ priv = ptpsq->txqsq.priv; ++ ++ mutex_lock(&priv->state_lock); ++ chs = &priv->channels; ++ netdev = priv->netdev; ++ ++ carrier_ok = netif_carrier_ok(netdev); ++ netif_carrier_off(netdev); ++ ++ mlx5e_deactivate_priv_channels(priv); ++ ++ mlx5e_ptp_close(chs->ptp); ++ err = mlx5e_ptp_open(priv, &chs->params, chs->c[0]->lag_port, &chs->ptp); ++ ++ mlx5e_activate_priv_channels(priv); ++ ++ /* return carrier back if needed */ ++ if (carrier_ok) ++ netif_carrier_on(netdev); ++ ++ mutex_unlock(&priv->state_lock); ++ ++ return err; ++} ++ + /* state lock cannot be grabbed within this function. + * It can cause a dead lock or a read-after-free. + */ +@@ -516,6 +553,15 @@ static int mlx5e_tx_reporter_timeout_dump(struct mlx5e_priv *priv, struct devlin + return mlx5e_tx_reporter_dump_sq(priv, fmsg, to_ctx->sq); + } + ++static int mlx5e_tx_reporter_ptpsq_unhealthy_dump(struct mlx5e_priv *priv, ++ struct devlink_fmsg *fmsg, ++ void *ctx) ++{ ++ struct mlx5e_ptpsq *ptpsq = ctx; ++ ++ return mlx5e_tx_reporter_dump_sq(priv, fmsg, &ptpsq->txqsq); ++} ++ + static int mlx5e_tx_reporter_dump_all_sqs(struct mlx5e_priv *priv, + struct devlink_fmsg *fmsg) + { +@@ -621,6 +667,25 @@ int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq) + return to_ctx.status; + } + ++void mlx5e_reporter_tx_ptpsq_unhealthy(struct mlx5e_ptpsq *ptpsq) ++{ ++ struct mlx5e_ptp_metadata_map *map = &ptpsq->metadata_map; ++ char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN]; ++ struct mlx5e_txqsq *txqsq = &ptpsq->txqsq; ++ struct mlx5e_cq *ts_cq = &ptpsq->ts_cq; ++ struct mlx5e_priv *priv = txqsq->priv; ++ struct mlx5e_err_ctx err_ctx = {}; ++ ++ err_ctx.ctx = ptpsq; ++ err_ctx.recover = mlx5e_tx_reporter_ptpsq_unhealthy_recover; ++ err_ctx.dump = mlx5e_tx_reporter_ptpsq_unhealthy_dump; ++ snprintf(err_str, sizeof(err_str), ++ "Unhealthy TX port TS queue: %d, SQ: 0x%x, CQ: 0x%x, Undelivered CQEs: %u Map Capacity: %u", ++ txqsq->ch_ix, txqsq->sqn, ts_cq->mcq.cqn, map->undelivered_counter, map->capacity); ++ ++ mlx5e_health_report(priv, priv->tx_reporter, err_str, &err_ctx); ++} ++ + static const struct devlink_health_reporter_ops mlx5_tx_reporter_ops = { + .name = "tx", + .recover = mlx5e_tx_reporter_recover, +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch b/queue-6.5/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch new file mode 100644 index 00000000000..c7736b8c393 --- /dev/null +++ b/queue-6.5/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch @@ -0,0 +1,72 @@ +From e98f8ce3098b6e5f50c64ba9b49a14a3df5d46d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:45 -0800 +Subject: net/mlx5e: Check return value of snprintf writing to fw_version + buffer + +From: Rahul Rameshbabu + +[ Upstream commit 41e63c2baa11dc2aa71df5dd27a5bd87d11b6bbb ] + +Treat the operation as an error case when the return value is equivalent to +the size of the name buffer. Failed to write null terminator to the name +buffer, making the string malformed and should not be used. Provide a +string with only the firmware version when forming the string with the +board id fails. + +Without check, will trigger -Wformat-truncation with W=1. + + drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c: In function 'mlx5e_ethtool_get_drvinfo': + drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c:49:31: warning: '%.16s' directive output may be truncated writing up to 16 bytes into a region of size between 13 and 22 [-Wformat-truncation=] + 49 | "%d.%d.%04d (%.16s)", + | ^~~~~ + drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c:48:9: note: 'snprintf' output between 12 and 37 bytes into a destination of size 32 + 48 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 49 | "%d.%d.%04d (%.16s)", + | ~~~~~~~~~~~~~~~~~~~~~ + 50 | fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 51 | mdev->board_id); + | ~~~~~~~~~~~~~~~ + +Fixes: 84e11edb71de ("net/mlx5e: Show board id in ethtool driver information") +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d4ab2e97dcfbcd748ae71761a9d8e5e41cc732c +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Dragos Tatulea +Signed-off-by: Saeed Mahameed +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index 3d2d5d3b59f0b..bd3fabb007c94 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -43,12 +43,17 @@ void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv, + struct ethtool_drvinfo *drvinfo) + { + struct mlx5_core_dev *mdev = priv->mdev; ++ int count; + + strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); +- snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), +- "%d.%d.%04d (%.16s)", +- fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev), +- mdev->board_id); ++ count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), ++ fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); ++ if (count == sizeof(drvinfo->fw_version)) ++ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%d.%d.%04d", fw_rev_maj(mdev), ++ fw_rev_min(mdev), fw_rev_sub(mdev)); ++ + strscpy(drvinfo->bus_info, dev_name(mdev->device), + sizeof(drvinfo->bus_info)); + } +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch-24193 b/queue-6.5/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch-24193 new file mode 100644 index 00000000000..d08e1d620bd --- /dev/null +++ b/queue-6.5/net-mlx5e-check-return-value-of-snprintf-writing-to-.patch-24193 @@ -0,0 +1,74 @@ +From 3964d49c0548dba295ce26da2db6dbd2be810a64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:46 -0800 +Subject: net/mlx5e: Check return value of snprintf writing to fw_version + buffer for representors + +From: Rahul Rameshbabu + +[ Upstream commit 1b2bd0c0264febcd8d47209079a6671c38e6558b ] + +Treat the operation as an error case when the return value is equivalent to +the size of the name buffer. Failed to write null terminator to the name +buffer, making the string malformed and should not be used. Provide a +string with only the firmware version when forming the string with the +board id fails. This logic for representors is identical to normal flow +with ethtool. + +Without check, will trigger -Wformat-truncation with W=1. + + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c: In function 'mlx5e_rep_get_drvinfo': + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c:78:31: warning: '%.16s' directive output may be truncated writing up to 16 bytes into a region of size between 13 and 22 [-Wformat-truncation=] + 78 | "%d.%d.%04d (%.16s)", + | ^~~~~ + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c:77:9: note: 'snprintf' output between 12 and 37 bytes into a destination of size 32 + 77 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 78 | "%d.%d.%04d (%.16s)", + | ~~~~~~~~~~~~~~~~~~~~~ + 79 | fw_rev_maj(mdev), fw_rev_min(mdev), + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 80 | fw_rev_sub(mdev), mdev->board_id); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: cf83c8fdcd47 ("net/mlx5e: Add missing ethtool driver info for representors") +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d4ab2e97dcfbcd748ae71761a9d8e5e41cc732c +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Dragos Tatulea +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-16-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index 0cd44ef190058..87fda65852fb7 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -71,13 +71,17 @@ static void mlx5e_rep_get_drvinfo(struct net_device *dev, + { + struct mlx5e_priv *priv = netdev_priv(dev); + struct mlx5_core_dev *mdev = priv->mdev; ++ int count; + + strscpy(drvinfo->driver, mlx5e_rep_driver_name, + sizeof(drvinfo->driver)); +- snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), +- "%d.%d.%04d (%.16s)", +- fw_rev_maj(mdev), fw_rev_min(mdev), +- fw_rev_sub(mdev), mdev->board_id); ++ count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), ++ fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); ++ if (count == sizeof(drvinfo->fw_version)) ++ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ++ "%d.%d.%04d", fw_rev_maj(mdev), ++ fw_rev_min(mdev), fw_rev_sub(mdev)); + } + + static const struct counter_desc sw_rep_stats_desc[] = { +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch b/queue-6.5/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch new file mode 100644 index 00000000000..ec99b894a4b --- /dev/null +++ b/queue-6.5/net-mlx5e-fix-double-free-of-encap_header-in-update-.patch @@ -0,0 +1,102 @@ +From b65daf698be5e8a9c0dc0b3a1ce6c774b17b7822 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:37 -0800 +Subject: net/mlx5e: fix double free of encap_header in update funcs + +From: Gavin Li + +[ Upstream commit 3a4aa3cb83563df942be49d145ee3b7ddf17d6bb ] + +Follow up to the previous patch to fix the same issue for +mlx5e_tc_tun_update_header_ipv4{6} when mlx5_packet_reformat_alloc() +fails. + +When mlx5_packet_reformat_alloc() fails, the encap_header allocated in +mlx5e_tc_tun_update_header_ipv4{6} will be released within it. However, +e->encap_header is already set to the previously freed encap_header +before mlx5_packet_reformat_alloc(). As a result, the later +mlx5e_encap_put() will free e->encap_header again, causing a double free +issue. + +mlx5e_encap_put() + --> mlx5e_encap_dealloc() + --> kfree(e->encap_header) + +This patch fix it by not setting e->encap_header until +mlx5_packet_reformat_alloc() success. + +Fixes: a54e20b4fcae ("net/mlx5e: Add basic TC tunnel set action for SRIOV offloads") +Signed-off-by: Gavin Li +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-7-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/core/en/tc_tun.c | 20 +++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +index 8bca696b6658c..668da5c70e63d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +@@ -403,16 +403,12 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, + if (err) + goto free_encap; + +- e->encap_size = ipv4_encap_size; +- kfree(e->encap_header); +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event + * and not used before that. + */ +- goto release_neigh; ++ goto free_encap; + } + + memset(&reformat_params, 0, sizeof(reformat_params)); +@@ -426,6 +422,10 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, + goto free_encap; + } + ++ e->encap_size = ipv4_encap_size; ++ kfree(e->encap_header); ++ e->encap_header = encap_header; ++ + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv4_put(&attr); +@@ -669,16 +669,12 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, + if (err) + goto free_encap; + +- e->encap_size = ipv6_encap_size; +- kfree(e->encap_header); +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event + * and not used before that. + */ +- goto release_neigh; ++ goto free_encap; + } + + memset(&reformat_params, 0, sizeof(reformat_params)); +@@ -692,6 +688,10 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, + goto free_encap; + } + ++ e->encap_size = ipv6_encap_size; ++ kfree(e->encap_header); ++ e->encap_header = encap_header; ++ + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv6_put(&attr); +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-fix-double-free-of-encap_header.patch b/queue-6.5/net-mlx5e-fix-double-free-of-encap_header.patch new file mode 100644 index 00000000000..3ba32efc656 --- /dev/null +++ b/queue-6.5/net-mlx5e-fix-double-free-of-encap_header.patch @@ -0,0 +1,82 @@ +From 31c8cfb6ff705c333c0aefa6cc1d05e9950bc71f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:36 -0800 +Subject: net/mlx5e: fix double free of encap_header + +From: Dust Li + +[ Upstream commit 6f9b1a0731662648949a1c0587f6acb3b7f8acf1 ] + +When mlx5_packet_reformat_alloc() fails, the encap_header allocated in +mlx5e_tc_tun_create_header_ipv4{6} will be released within it. However, +e->encap_header is already set to the previously freed encap_header +before mlx5_packet_reformat_alloc(). As a result, the later +mlx5e_encap_put() will free e->encap_header again, causing a double free +issue. + +mlx5e_encap_put() + --> mlx5e_encap_dealloc() + --> kfree(e->encap_header) + +This happens when cmd: MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT fail. + +This patch fix it by not setting e->encap_header until +mlx5_packet_reformat_alloc() success. + +Fixes: d589e785baf5e ("net/mlx5e: Allow concurrent creation of encap entries") +Reported-by: Cruz Zhao +Reported-by: Tianchen Ding +Signed-off-by: Dust Li +Reviewed-by: Wojciech Drewek +Signed-off-by: Saeed Mahameed +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +index 00a04fdd756f5..8bca696b6658c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +@@ -300,9 +300,6 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, + if (err) + goto destroy_neigh_entry; + +- e->encap_size = ipv4_encap_size; +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event +@@ -322,6 +319,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, + goto destroy_neigh_entry; + } + ++ e->encap_size = ipv4_encap_size; ++ e->encap_header = encap_header; + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv4_put(&attr); +@@ -568,9 +567,6 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, + if (err) + goto destroy_neigh_entry; + +- e->encap_size = ipv6_encap_size; +- e->encap_header = encap_header; +- + if (!(nud_state & NUD_VALID)) { + neigh_event_send(attr.n, NULL); + /* the encap entry will be made valid on neigh update event +@@ -590,6 +586,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, + goto destroy_neigh_entry; + } + ++ e->encap_size = ipv6_encap_size; ++ e->encap_header = encap_header; + e->flags |= MLX5_ENCAP_ENTRY_VALID; + mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); + mlx5e_route_lookup_ipv6_put(&attr); +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-fix-pedit-endianness.patch b/queue-6.5/net-mlx5e-fix-pedit-endianness.patch new file mode 100644 index 00000000000..391ccea46a5 --- /dev/null +++ b/queue-6.5/net-mlx5e-fix-pedit-endianness.patch @@ -0,0 +1,174 @@ +From 2d488fc00cc0d93cb086e770b562c17a56bdd47b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:38 -0800 +Subject: net/mlx5e: Fix pedit endianness + +From: Vlad Buslov + +[ Upstream commit 0c101a23ca7eaf00eef1328eefb04b3a93401cc8 ] + +Referenced commit addressed endianness issue in mlx5 pedit implementation +in ad hoc manner instead of systematically treating integer values +according to their types which left pedit fields of sizes not equal to 4 +and where the bytes being modified are not least significant ones broken on +big endian machines since wrong bits will be consumed during parsing which +leads to following example error when applying pedit to source and +destination MAC addresses: + +[Wed Oct 18 12:52:42 2023] mlx5_core 0001:00:00.1 p1v3_r: attempt to offload an unsupported field (cmd 0) +[Wed Oct 18 12:52:42 2023] mask: 00000000330c5b68: 00 00 00 00 ff ff 00 00 00 00 ff ff 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 0000000017d22fd9: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 000000008186d717: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 0000000029eb6149: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 000000007ed103e4: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 00000000db8101a6: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +[Wed Oct 18 12:52:42 2023] mask: 00000000ec3c08a9: 00 00 00 00 00 00 00 00 00 00 00 00 ............ + +Treat masks and values of pedit and filter match as network byte order, +refactor pointers to them to void pointers instead of confusing u32 +pointers and only cast to pointer-to-integer when reading a value from +them. Treat pedit mlx5_fields->field_mask as host byte order according to +its type u32, change the constants in fields array accordingly. + +Fixes: 82198d8bcdef ("net/mlx5e: Fix endianness when calculating pedit mask first bit") +Signed-off-by: Vlad Buslov +Reviewed-by: Gal Pressman +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-8-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_tc.c | 60 ++++++++++--------- + 1 file changed, 32 insertions(+), 28 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 5797d8607633e..fdef505c4b88f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -3148,7 +3148,7 @@ static struct mlx5_fields fields[] = { + OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0, + dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]), + OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit), +- OFFLOAD(IP_DSCP, 16, 0xc00f, ip6, 0, ip_dscp), ++ OFFLOAD(IP_DSCP, 16, 0x0fc0, ip6, 0, ip_dscp), + + OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport), + OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport), +@@ -3159,21 +3159,31 @@ static struct mlx5_fields fields[] = { + OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport), + }; + +-static unsigned long mask_to_le(unsigned long mask, int size) ++static u32 mask_field_get(void *mask, struct mlx5_fields *f) + { +- __be32 mask_be32; +- __be16 mask_be16; +- +- if (size == 32) { +- mask_be32 = (__force __be32)(mask); +- mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); +- } else if (size == 16) { +- mask_be32 = (__force __be32)(mask); +- mask_be16 = *(__be16 *)&mask_be32; +- mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); ++ switch (f->field_bsize) { ++ case 32: ++ return be32_to_cpu(*(__be32 *)mask) & f->field_mask; ++ case 16: ++ return be16_to_cpu(*(__be16 *)mask) & (u16)f->field_mask; ++ default: ++ return *(u8 *)mask & (u8)f->field_mask; + } ++} + +- return mask; ++static void mask_field_clear(void *mask, struct mlx5_fields *f) ++{ ++ switch (f->field_bsize) { ++ case 32: ++ *(__be32 *)mask &= ~cpu_to_be32(f->field_mask); ++ break; ++ case 16: ++ *(__be16 *)mask &= ~cpu_to_be16((u16)f->field_mask); ++ break; ++ default: ++ *(u8 *)mask &= ~(u8)f->field_mask; ++ break; ++ } + } + + static int offload_pedit_fields(struct mlx5e_priv *priv, +@@ -3185,11 +3195,12 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; + struct pedit_headers_action *hdrs = parse_attr->hdrs; + void *headers_c, *headers_v, *action, *vals_p; +- u32 *s_masks_p, *a_masks_p, s_mask, a_mask; + struct mlx5e_tc_mod_hdr_acts *mod_acts; +- unsigned long mask, field_mask; ++ void *s_masks_p, *a_masks_p; + int i, first, last, next_z; + struct mlx5_fields *f; ++ unsigned long mask; ++ u32 s_mask, a_mask; + u8 cmd; + + mod_acts = &parse_attr->mod_hdr_acts; +@@ -3205,15 +3216,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + bool skip; + + f = &fields[i]; +- /* avoid seeing bits set from previous iterations */ +- s_mask = 0; +- a_mask = 0; +- + s_masks_p = (void *)set_masks + f->offset; + a_masks_p = (void *)add_masks + f->offset; + +- s_mask = *s_masks_p & f->field_mask; +- a_mask = *a_masks_p & f->field_mask; ++ s_mask = mask_field_get(s_masks_p, f); ++ a_mask = mask_field_get(a_masks_p, f); + + if (!s_mask && !a_mask) /* nothing to offload here */ + continue; +@@ -3240,22 +3247,20 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + match_mask, f->field_bsize)) + skip = true; + /* clear to denote we consumed this field */ +- *s_masks_p &= ~f->field_mask; ++ mask_field_clear(s_masks_p, f); + } else { + cmd = MLX5_ACTION_TYPE_ADD; + mask = a_mask; + vals_p = (void *)add_vals + f->offset; + /* add 0 is no change */ +- if ((*(u32 *)vals_p & f->field_mask) == 0) ++ if (!mask_field_get(vals_p, f)) + skip = true; + /* clear to denote we consumed this field */ +- *a_masks_p &= ~f->field_mask; ++ mask_field_clear(a_masks_p, f); + } + if (skip) + continue; + +- mask = mask_to_le(mask, f->field_bsize); +- + first = find_first_bit(&mask, f->field_bsize); + next_z = find_next_zero_bit(&mask, f->field_bsize, first); + last = find_last_bit(&mask, f->field_bsize); +@@ -3282,10 +3287,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, + MLX5_SET(set_action_in, action, field, f->field); + + if (cmd == MLX5_ACTION_TYPE_SET) { ++ unsigned long field_mask = f->field_mask; + int start; + +- field_mask = mask_to_le(f->field_mask, f->field_bsize); +- + /* if field is bit sized it can start not from first bit */ + start = find_first_bit(&field_mask, f->field_bsize); + +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-make-tx_port_ts-logic-resilient-to-out-of-.patch b/queue-6.5/net-mlx5e-make-tx_port_ts-logic-resilient-to-out-of-.patch new file mode 100644 index 00000000000..0bc9bd2aad2 --- /dev/null +++ b/queue-6.5/net-mlx5e-make-tx_port_ts-logic-resilient-to-out-of-.patch @@ -0,0 +1,627 @@ +From 3f96eab3a0023d1bebe18a51c6f41db58c53f82d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 May 2023 16:31:40 -0700 +Subject: net/mlx5e: Make tx_port_ts logic resilient to out-of-order CQEs + +From: Rahul Rameshbabu + +[ Upstream commit 3178308ad4ca38955cad684d235153d4939f1fcd ] + +Use a map structure for associating CQEs containing port timestamping +information with the appropriate skb. Track order of WQEs submitted using a +FIFO. Check if the corresponding port timestamping CQEs from the lookup +values in the FIFO are considered dropped due to time elapsed. Return the +lookup value to a freelist after consuming the skb. Reuse the freed lookup +in future WQE submission iterations. + +The map structure uses an integer identifier for the key and returns an skb +corresponding to that identifier. Embed the integer identifier in the WQE +submitted to the WQ for the transmit path when the SQ is a PTP (port +timestamping) SQ. The embedded identifier can then be queried using a field +in the CQE of the corresponding port timestamping CQ. In the port +timestamping napi_poll context, the identifier is queried from the CQE +polled from CQ and used to lookup the corresponding skb from the WQE submit +path. The skb reference is removed from map and then embedded with the port +HW timestamp information from the CQE and eventually consumed. + +The metadata freelist FIFO is an array containing integer identifiers that +can be pushed and popped in the FIFO. The purpose of this structure is +bookkeeping what identifier values can safely be used in a subsequent WQE +submission and should not contain identifiers that have still not been +reaped by processing a corresponding CQE completion on the port +timestamping CQ. + +The ts_cqe_pending_list structure is a combination of an array and linked +list. The array is pre-populated with the nodes that will be added and +removed from the head of the linked list. Each node contains the unique +identifier value associated with the values submitted in the WQEs and +retrieved in the port timestamping CQEs. When a WQE is submitted, the node +in the array corresponding to the identifier popped from the metadata +freelist is added to the end of the CQE pending list and is marked as +"in-use". The node is removed from the linked list under two conditions. +The first condition is that the corresponding port timestamping CQE is +polled in the PTP napi_poll context. The second condition is that more than +a second has elapsed since the DMA timestamp value corresponding to the WQE +submission. When the first condition occurs, the "in-use" bit in the linked +list node is cleared, and the resources corresponding to the WQE submission +are then released. The second condition, however, indicates that the port +timestamping CQE will likely never be delivered. It's not impossible for +the device to post a CQE after an infinite amount of time though highly +improbable. In order to be resilient to this improbable case, resources +related to the corresponding WQE submission are still kept, the identifier +value is not returned to the freelist, and the "in-use" bit is cleared on +the node to indicate that it's no longer part of the linked list of "likely +to be delivered" port timestamping CQE identifiers. A count for the number +of port timestamping CQEs considered highly likely to never be delivered by +the device is maintained. This count gets decremented in the unlikely event +a port timestamping CQE considered unlikely to ever be delivered is polled +in the PTP napi_poll context. + +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Stable-dep-of: 92214be5979c ("net/mlx5e: Update doorbell for port timestamping CQ before the software counter") +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/counters.rst | 6 + + .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 215 +++++++++++++----- + .../net/ethernet/mellanox/mlx5/core/en/ptp.h | 57 ++++- + .../ethernet/mellanox/mlx5/core/en_ethtool.c | 3 +- + .../ethernet/mellanox/mlx5/core/en_stats.c | 4 +- + .../ethernet/mellanox/mlx5/core/en_stats.h | 4 +- + .../net/ethernet/mellanox/mlx5/core/en_tx.c | 28 ++- + 7 files changed, 236 insertions(+), 81 deletions(-) + +diff --git a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/counters.rst b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/counters.rst +index a395df9c27513..008e560e12b58 100644 +--- a/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/counters.rst ++++ b/Documentation/networking/device_drivers/ethernet/mellanox/mlx5/counters.rst +@@ -683,6 +683,12 @@ the software port. + time protocol. + - Error + ++ * - `ptp_cq[i]_late_cqe` ++ - Number of times a CQE has been delivered on the PTP timestamping CQ when ++ the CQE was not expected since a certain amount of time had elapsed where ++ the device typically ensures not posting the CQE. ++ - Error ++ + .. [#ring_global] The corresponding ring and global counters do not share the + same name (i.e. do not follow the common naming scheme). + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +index b0b429a0321ed..8680d21f3e7b0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +@@ -5,6 +5,8 @@ + #include "en/txrx.h" + #include "en/params.h" + #include "en/fs_tt_redirect.h" ++#include ++#include + + struct mlx5e_ptp_fs { + struct mlx5_flow_handle *l2_rule; +@@ -19,6 +21,48 @@ struct mlx5e_ptp_params { + struct mlx5e_rq_param rq_param; + }; + ++struct mlx5e_ptp_port_ts_cqe_tracker { ++ u8 metadata_id; ++ bool inuse : 1; ++ struct list_head entry; ++}; ++ ++struct mlx5e_ptp_port_ts_cqe_list { ++ struct mlx5e_ptp_port_ts_cqe_tracker *nodes; ++ struct list_head tracker_list_head; ++ /* Sync list operations in xmit and napi_poll contexts */ ++ spinlock_t tracker_list_lock; ++}; ++ ++static inline void ++mlx5e_ptp_port_ts_cqe_list_add(struct mlx5e_ptp_port_ts_cqe_list *list, u8 metadata) ++{ ++ struct mlx5e_ptp_port_ts_cqe_tracker *tracker = &list->nodes[metadata]; ++ ++ WARN_ON_ONCE(tracker->inuse); ++ tracker->inuse = true; ++ spin_lock(&list->tracker_list_lock); ++ list_add_tail(&tracker->entry, &list->tracker_list_head); ++ spin_unlock(&list->tracker_list_lock); ++} ++ ++static void ++mlx5e_ptp_port_ts_cqe_list_remove(struct mlx5e_ptp_port_ts_cqe_list *list, u8 metadata) ++{ ++ struct mlx5e_ptp_port_ts_cqe_tracker *tracker = &list->nodes[metadata]; ++ ++ WARN_ON_ONCE(!tracker->inuse); ++ tracker->inuse = false; ++ spin_lock(&list->tracker_list_lock); ++ list_del(&tracker->entry); ++ spin_unlock(&list->tracker_list_lock); ++} ++ ++void mlx5e_ptpsq_track_metadata(struct mlx5e_ptpsq *ptpsq, u8 metadata) ++{ ++ mlx5e_ptp_port_ts_cqe_list_add(ptpsq->ts_cqe_pending_list, metadata); ++} ++ + struct mlx5e_skb_cb_hwtstamp { + ktime_t cqe_hwtstamp; + ktime_t port_hwtstamp; +@@ -79,75 +123,88 @@ void mlx5e_skb_cb_hwtstamp_handler(struct sk_buff *skb, int hwtstamp_type, + memset(skb->cb, 0, sizeof(struct mlx5e_skb_cb_hwtstamp)); + } + +-#define PTP_WQE_CTR2IDX(val) ((val) & ptpsq->ts_cqe_ctr_mask) +- +-static bool mlx5e_ptp_ts_cqe_drop(struct mlx5e_ptpsq *ptpsq, u16 skb_ci, u16 skb_id) ++static struct sk_buff * ++mlx5e_ptp_metadata_map_lookup(struct mlx5e_ptp_metadata_map *map, u16 metadata) + { +- return (ptpsq->ts_cqe_ctr_mask && (skb_ci != skb_id)); ++ return map->data[metadata]; + } + +-static bool mlx5e_ptp_ts_cqe_ooo(struct mlx5e_ptpsq *ptpsq, u16 skb_id) ++static struct sk_buff * ++mlx5e_ptp_metadata_map_remove(struct mlx5e_ptp_metadata_map *map, u16 metadata) + { +- u16 skb_ci = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_cc); +- u16 skb_pi = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_pc); ++ struct sk_buff *skb; + +- if (PTP_WQE_CTR2IDX(skb_id - skb_ci) >= PTP_WQE_CTR2IDX(skb_pi - skb_ci)) +- return true; ++ skb = map->data[metadata]; ++ map->data[metadata] = NULL; + +- return false; ++ return skb; + } + +-static void mlx5e_ptp_skb_fifo_ts_cqe_resync(struct mlx5e_ptpsq *ptpsq, u16 skb_ci, +- u16 skb_id, int budget) ++static void mlx5e_ptpsq_mark_ts_cqes_undelivered(struct mlx5e_ptpsq *ptpsq, ++ ktime_t port_tstamp) + { +- struct skb_shared_hwtstamps hwts = {}; +- struct sk_buff *skb; ++ struct mlx5e_ptp_port_ts_cqe_list *cqe_list = ptpsq->ts_cqe_pending_list; ++ ktime_t timeout = ns_to_ktime(MLX5E_PTP_TS_CQE_UNDELIVERED_TIMEOUT); ++ struct mlx5e_ptp_metadata_map *metadata_map = &ptpsq->metadata_map; ++ struct mlx5e_ptp_port_ts_cqe_tracker *pos, *n; ++ ++ spin_lock(&cqe_list->tracker_list_lock); ++ list_for_each_entry_safe(pos, n, &cqe_list->tracker_list_head, entry) { ++ struct sk_buff *skb = ++ mlx5e_ptp_metadata_map_lookup(metadata_map, pos->metadata_id); ++ ktime_t dma_tstamp = mlx5e_skb_cb_get_hwts(skb)->cqe_hwtstamp; + +- ptpsq->cq_stats->resync_event++; ++ if (!dma_tstamp || ++ ktime_after(ktime_add(dma_tstamp, timeout), port_tstamp)) ++ break; + +- while (skb_ci != skb_id) { +- skb = mlx5e_skb_fifo_pop(&ptpsq->skb_fifo); +- hwts.hwtstamp = mlx5e_skb_cb_get_hwts(skb)->cqe_hwtstamp; +- skb_tstamp_tx(skb, &hwts); +- ptpsq->cq_stats->resync_cqe++; +- napi_consume_skb(skb, budget); +- skb_ci = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_cc); ++ metadata_map->undelivered_counter++; ++ WARN_ON_ONCE(!pos->inuse); ++ pos->inuse = false; ++ list_del(&pos->entry); + } ++ spin_unlock(&cqe_list->tracker_list_lock); + } + ++#define PTP_WQE_CTR2IDX(val) ((val) & ptpsq->ts_cqe_ctr_mask) ++ + static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, + struct mlx5_cqe64 *cqe, + int budget) + { +- u16 skb_id = PTP_WQE_CTR2IDX(be16_to_cpu(cqe->wqe_counter)); +- u16 skb_ci = PTP_WQE_CTR2IDX(ptpsq->skb_fifo_cc); ++ struct mlx5e_ptp_port_ts_cqe_list *pending_cqe_list = ptpsq->ts_cqe_pending_list; ++ u8 metadata_id = PTP_WQE_CTR2IDX(be16_to_cpu(cqe->wqe_counter)); ++ bool is_err_cqe = !!MLX5E_RX_ERR_CQE(cqe); + struct mlx5e_txqsq *sq = &ptpsq->txqsq; + struct sk_buff *skb; + ktime_t hwtstamp; + +- if (unlikely(MLX5E_RX_ERR_CQE(cqe))) { +- skb = mlx5e_skb_fifo_pop(&ptpsq->skb_fifo); +- ptpsq->cq_stats->err_cqe++; +- goto out; ++ if (likely(pending_cqe_list->nodes[metadata_id].inuse)) { ++ mlx5e_ptp_port_ts_cqe_list_remove(pending_cqe_list, metadata_id); ++ } else { ++ /* Reclaim space in the unlikely event CQE was delivered after ++ * marking it late. ++ */ ++ ptpsq->metadata_map.undelivered_counter--; ++ ptpsq->cq_stats->late_cqe++; + } + +- if (mlx5e_ptp_ts_cqe_drop(ptpsq, skb_ci, skb_id)) { +- if (mlx5e_ptp_ts_cqe_ooo(ptpsq, skb_id)) { +- /* already handled by a previous resync */ +- ptpsq->cq_stats->ooo_cqe_drop++; +- return; +- } +- mlx5e_ptp_skb_fifo_ts_cqe_resync(ptpsq, skb_ci, skb_id, budget); ++ skb = mlx5e_ptp_metadata_map_remove(&ptpsq->metadata_map, metadata_id); ++ ++ if (unlikely(is_err_cqe)) { ++ ptpsq->cq_stats->err_cqe++; ++ goto out; + } + +- skb = mlx5e_skb_fifo_pop(&ptpsq->skb_fifo); + hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, get_cqe_ts(cqe)); + mlx5e_skb_cb_hwtstamp_handler(skb, MLX5E_SKB_CB_PORT_HWTSTAMP, + hwtstamp, ptpsq->cq_stats); + ptpsq->cq_stats->cqe++; + ++ mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp); + out: + napi_consume_skb(skb, budget); ++ mlx5e_ptp_metadata_fifo_push(&ptpsq->metadata_freelist, metadata_id); + } + + static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) +@@ -291,36 +348,78 @@ static void mlx5e_ptp_destroy_sq(struct mlx5_core_dev *mdev, u32 sqn) + + static int mlx5e_ptp_alloc_traffic_db(struct mlx5e_ptpsq *ptpsq, int numa) + { +- int wq_sz = mlx5_wq_cyc_get_size(&ptpsq->txqsq.wq); +- struct mlx5_core_dev *mdev = ptpsq->txqsq.mdev; ++ struct mlx5e_ptp_metadata_fifo *metadata_freelist = &ptpsq->metadata_freelist; ++ struct mlx5e_ptp_metadata_map *metadata_map = &ptpsq->metadata_map; ++ struct mlx5e_ptp_port_ts_cqe_list *cqe_list; ++ int db_sz; ++ int md; + +- ptpsq->skb_fifo.fifo = kvzalloc_node(array_size(wq_sz, sizeof(*ptpsq->skb_fifo.fifo)), +- GFP_KERNEL, numa); +- if (!ptpsq->skb_fifo.fifo) ++ cqe_list = kvzalloc_node(sizeof(*ptpsq->ts_cqe_pending_list), GFP_KERNEL, numa); ++ if (!cqe_list) + return -ENOMEM; ++ ptpsq->ts_cqe_pending_list = cqe_list; ++ ++ db_sz = min_t(u32, mlx5_wq_cyc_get_size(&ptpsq->txqsq.wq), ++ 1 << MLX5_CAP_GEN_2(ptpsq->txqsq.mdev, ++ ts_cqe_metadata_size2wqe_counter)); ++ ptpsq->ts_cqe_ctr_mask = db_sz - 1; ++ ++ cqe_list->nodes = kvzalloc_node(array_size(db_sz, sizeof(*cqe_list->nodes)), ++ GFP_KERNEL, numa); ++ if (!cqe_list->nodes) ++ goto free_cqe_list; ++ INIT_LIST_HEAD(&cqe_list->tracker_list_head); ++ spin_lock_init(&cqe_list->tracker_list_lock); ++ ++ metadata_freelist->data = ++ kvzalloc_node(array_size(db_sz, sizeof(*metadata_freelist->data)), ++ GFP_KERNEL, numa); ++ if (!metadata_freelist->data) ++ goto free_cqe_list_nodes; ++ metadata_freelist->mask = ptpsq->ts_cqe_ctr_mask; ++ ++ for (md = 0; md < db_sz; ++md) { ++ cqe_list->nodes[md].metadata_id = md; ++ metadata_freelist->data[md] = md; ++ } ++ metadata_freelist->pc = db_sz; ++ ++ metadata_map->data = ++ kvzalloc_node(array_size(db_sz, sizeof(*metadata_map->data)), ++ GFP_KERNEL, numa); ++ if (!metadata_map->data) ++ goto free_metadata_freelist; ++ metadata_map->capacity = db_sz; + +- ptpsq->skb_fifo.pc = &ptpsq->skb_fifo_pc; +- ptpsq->skb_fifo.cc = &ptpsq->skb_fifo_cc; +- ptpsq->skb_fifo.mask = wq_sz - 1; +- if (MLX5_CAP_GEN_2(mdev, ts_cqe_metadata_size2wqe_counter)) +- ptpsq->ts_cqe_ctr_mask = +- (1 << MLX5_CAP_GEN_2(mdev, ts_cqe_metadata_size2wqe_counter)) - 1; + return 0; ++ ++free_metadata_freelist: ++ kvfree(metadata_freelist->data); ++free_cqe_list_nodes: ++ kvfree(cqe_list->nodes); ++free_cqe_list: ++ kvfree(cqe_list); ++ return -ENOMEM; + } + +-static void mlx5e_ptp_drain_skb_fifo(struct mlx5e_skb_fifo *skb_fifo) ++static void mlx5e_ptp_drain_metadata_map(struct mlx5e_ptp_metadata_map *map) + { +- while (*skb_fifo->pc != *skb_fifo->cc) { +- struct sk_buff *skb = mlx5e_skb_fifo_pop(skb_fifo); ++ int idx; ++ ++ for (idx = 0; idx < map->capacity; ++idx) { ++ struct sk_buff *skb = map->data[idx]; + + dev_kfree_skb_any(skb); + } + } + +-static void mlx5e_ptp_free_traffic_db(struct mlx5e_skb_fifo *skb_fifo) ++static void mlx5e_ptp_free_traffic_db(struct mlx5e_ptpsq *ptpsq) + { +- mlx5e_ptp_drain_skb_fifo(skb_fifo); +- kvfree(skb_fifo->fifo); ++ mlx5e_ptp_drain_metadata_map(&ptpsq->metadata_map); ++ kvfree(ptpsq->metadata_map.data); ++ kvfree(ptpsq->metadata_freelist.data); ++ kvfree(ptpsq->ts_cqe_pending_list->nodes); ++ kvfree(ptpsq->ts_cqe_pending_list); + } + + static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, +@@ -348,8 +447,7 @@ static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, + if (err) + goto err_free_txqsq; + +- err = mlx5e_ptp_alloc_traffic_db(ptpsq, +- dev_to_node(mlx5_core_dma_dev(c->mdev))); ++ err = mlx5e_ptp_alloc_traffic_db(ptpsq, dev_to_node(mlx5_core_dma_dev(c->mdev))); + if (err) + goto err_free_txqsq; + +@@ -366,7 +464,7 @@ static void mlx5e_ptp_close_txqsq(struct mlx5e_ptpsq *ptpsq) + struct mlx5e_txqsq *sq = &ptpsq->txqsq; + struct mlx5_core_dev *mdev = sq->mdev; + +- mlx5e_ptp_free_traffic_db(&ptpsq->skb_fifo); ++ mlx5e_ptp_free_traffic_db(ptpsq); + cancel_work_sync(&sq->recover_work); + mlx5e_ptp_destroy_sq(mdev, sq->sqn); + mlx5e_free_txqsq_descs(sq); +@@ -534,7 +632,10 @@ static void mlx5e_ptp_build_params(struct mlx5e_ptp *c, + + /* SQ */ + if (test_bit(MLX5E_PTP_STATE_TX, c->state)) { +- params->log_sq_size = orig->log_sq_size; ++ params->log_sq_size = ++ min(MLX5_CAP_GEN_2(c->mdev, ts_cqe_metadata_size2wqe_counter), ++ MLX5E_PTP_MAX_LOG_SQ_SIZE); ++ params->log_sq_size = min(params->log_sq_size, orig->log_sq_size); + mlx5e_ptp_build_sq_param(c->mdev, params, &cparams->txq_sq_param); + } + /* RQ */ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h +index cc7efde88ac3c..7c5597d4589df 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h +@@ -7,18 +7,36 @@ + #include "en.h" + #include "en_stats.h" + #include "en/txrx.h" ++#include + #include ++#include + + #define MLX5E_PTP_CHANNEL_IX 0 ++#define MLX5E_PTP_MAX_LOG_SQ_SIZE (8U) ++#define MLX5E_PTP_TS_CQE_UNDELIVERED_TIMEOUT (1 * NSEC_PER_SEC) ++ ++struct mlx5e_ptp_metadata_fifo { ++ u8 cc; ++ u8 pc; ++ u8 mask; ++ u8 *data; ++}; ++ ++struct mlx5e_ptp_metadata_map { ++ u16 undelivered_counter; ++ u16 capacity; ++ struct sk_buff **data; ++}; + + struct mlx5e_ptpsq { + struct mlx5e_txqsq txqsq; + struct mlx5e_cq ts_cq; +- u16 skb_fifo_cc; +- u16 skb_fifo_pc; +- struct mlx5e_skb_fifo skb_fifo; + struct mlx5e_ptp_cq_stats *cq_stats; + u16 ts_cqe_ctr_mask; ++ ++ struct mlx5e_ptp_port_ts_cqe_list *ts_cqe_pending_list; ++ struct mlx5e_ptp_metadata_fifo metadata_freelist; ++ struct mlx5e_ptp_metadata_map metadata_map; + }; + + enum { +@@ -69,12 +87,35 @@ static inline bool mlx5e_use_ptpsq(struct sk_buff *skb) + fk.ports.dst == htons(PTP_EV_PORT)); + } + +-static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq) ++static inline void mlx5e_ptp_metadata_fifo_push(struct mlx5e_ptp_metadata_fifo *fifo, u8 metadata) + { +- if (!sq->ptpsq) +- return true; ++ fifo->data[fifo->mask & fifo->pc++] = metadata; ++} ++ ++static inline u8 ++mlx5e_ptp_metadata_fifo_pop(struct mlx5e_ptp_metadata_fifo *fifo) ++{ ++ return fifo->data[fifo->mask & fifo->cc++]; ++} + +- return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo); ++static inline void ++mlx5e_ptp_metadata_map_put(struct mlx5e_ptp_metadata_map *map, ++ struct sk_buff *skb, u8 metadata) ++{ ++ WARN_ON_ONCE(map->data[metadata]); ++ map->data[metadata] = skb; ++} ++ ++static inline bool mlx5e_ptpsq_metadata_freelist_empty(struct mlx5e_ptpsq *ptpsq) ++{ ++ struct mlx5e_ptp_metadata_fifo *freelist; ++ ++ if (likely(!ptpsq)) ++ return false; ++ ++ freelist = &ptpsq->metadata_freelist; ++ ++ return freelist->pc == freelist->cc; + } + + int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params, +@@ -89,6 +130,8 @@ void mlx5e_ptp_free_rx_fs(struct mlx5e_flow_steering *fs, + const struct mlx5e_profile *profile); + int mlx5e_ptp_rx_manage_fs(struct mlx5e_priv *priv, bool set); + ++void mlx5e_ptpsq_track_metadata(struct mlx5e_ptpsq *ptpsq, u8 metadata); ++ + enum { + MLX5E_SKB_CB_CQE_HWTSTAMP = BIT(0), + MLX5E_SKB_CB_PORT_HWTSTAMP = BIT(1), +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index 27861b68ced57..3d2d5d3b59f0b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -2061,7 +2061,8 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable) + struct mlx5e_params new_params; + int err; + +- if (!MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn)) ++ if (!MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn) || ++ !MLX5_CAP_GEN_2(mdev, ts_cqe_metadata_size2wqe_counter)) + return -EOPNOTSUPP; + + /* Don't allow changing the PTP state if HTB offload is active, because +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +index 4d77055abd4be..dfdd357974164 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +@@ -2142,9 +2142,7 @@ static const struct counter_desc ptp_cq_stats_desc[] = { + { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, err_cqe) }, + { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort) }, + { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort_abs_diff_ns) }, +- { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, resync_cqe) }, +- { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, resync_event) }, +- { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, ooo_cqe_drop) }, ++ { MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, late_cqe) }, + }; + + static const struct counter_desc ptp_rq_stats_desc[] = { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +index 67938b4ea1b90..13a07e52ae92b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +@@ -449,9 +449,7 @@ struct mlx5e_ptp_cq_stats { + u64 err_cqe; + u64 abort; + u64 abort_abs_diff_ns; +- u64 resync_cqe; +- u64 resync_event; +- u64 ooo_cqe_drop; ++ u64 late_cqe; + }; + + struct mlx5e_rep_stats { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +index c7eb6b238c2ba..d41435c22ce56 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +@@ -372,7 +372,7 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb, + const struct mlx5e_tx_attr *attr, + const struct mlx5e_tx_wqe_attr *wqe_attr, u8 num_dma, + struct mlx5e_tx_wqe_info *wi, struct mlx5_wqe_ctrl_seg *cseg, +- bool xmit_more) ++ struct mlx5_wqe_eth_seg *eseg, bool xmit_more) + { + struct mlx5_wq_cyc *wq = &sq->wq; + bool send_doorbell; +@@ -394,11 +394,16 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb, + + mlx5e_tx_check_stop(sq); + +- if (unlikely(sq->ptpsq)) { ++ if (unlikely(sq->ptpsq && ++ (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { ++ u8 metadata_index = be32_to_cpu(eseg->flow_table_metadata); ++ + mlx5e_skb_cb_hwtstamp_init(skb); +- mlx5e_skb_fifo_push(&sq->ptpsq->skb_fifo, skb); ++ mlx5e_ptpsq_track_metadata(sq->ptpsq, metadata_index); ++ mlx5e_ptp_metadata_map_put(&sq->ptpsq->metadata_map, skb, ++ metadata_index); + if (!netif_tx_queue_stopped(sq->txq) && +- !mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo)) { ++ mlx5e_ptpsq_metadata_freelist_empty(sq->ptpsq)) { + netif_tx_stop_queue(sq->txq); + sq->stats->stopped++; + } +@@ -483,13 +488,16 @@ mlx5e_sq_xmit_wqe(struct mlx5e_txqsq *sq, struct sk_buff *skb, + if (unlikely(num_dma < 0)) + goto err_drop; + +- mlx5e_txwqe_complete(sq, skb, attr, wqe_attr, num_dma, wi, cseg, xmit_more); ++ mlx5e_txwqe_complete(sq, skb, attr, wqe_attr, num_dma, wi, cseg, eseg, xmit_more); + + return; + + err_drop: + stats->dropped++; + dev_kfree_skb_any(skb); ++ if (unlikely(sq->ptpsq && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) ++ mlx5e_ptp_metadata_fifo_push(&sq->ptpsq->metadata_freelist, ++ be32_to_cpu(eseg->flow_table_metadata)); + mlx5e_tx_flush(sq); + } + +@@ -645,9 +653,9 @@ void mlx5e_tx_mpwqe_ensure_complete(struct mlx5e_txqsq *sq) + static void mlx5e_cqe_ts_id_eseg(struct mlx5e_ptpsq *ptpsq, struct sk_buff *skb, + struct mlx5_wqe_eth_seg *eseg) + { +- if (ptpsq->ts_cqe_ctr_mask && unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) +- eseg->flow_table_metadata = cpu_to_be32(ptpsq->skb_fifo_pc & +- ptpsq->ts_cqe_ctr_mask); ++ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) ++ eseg->flow_table_metadata = ++ cpu_to_be32(mlx5e_ptp_metadata_fifo_pop(&ptpsq->metadata_freelist)); + } + + static void mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq, +@@ -766,7 +774,7 @@ void mlx5e_txqsq_wake(struct mlx5e_txqsq *sq) + { + if (netif_tx_queue_stopped(sq->txq) && + mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) && +- mlx5e_ptpsq_fifo_has_room(sq) && ++ !mlx5e_ptpsq_metadata_freelist_empty(sq->ptpsq) && + !test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) { + netif_tx_wake_queue(sq->txq); + sq->stats->wake++; +@@ -1031,7 +1039,7 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, + if (unlikely(num_dma < 0)) + goto err_drop; + +- mlx5e_txwqe_complete(sq, skb, &attr, &wqe_attr, num_dma, wi, cseg, xmit_more); ++ mlx5e_txwqe_complete(sq, skb, &attr, &wqe_attr, num_dma, wi, cseg, eseg, xmit_more); + + return; + +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-reduce-the-size-of-icosq_str.patch b/queue-6.5/net-mlx5e-reduce-the-size-of-icosq_str.patch new file mode 100644 index 00000000000..7719efa1a97 --- /dev/null +++ b/queue-6.5/net-mlx5e-reduce-the-size-of-icosq_str.patch @@ -0,0 +1,73 @@ +From 7326bd68374ab74574cf0c4262ced91702b0c00c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:44 -0800 +Subject: net/mlx5e: Reduce the size of icosq_str + +From: Saeed Mahameed + +[ Upstream commit dce94142842e119b982c27c1b62bd20890c7fd21 ] + +icosq_str size is unnecessarily too long, and it causes a build warning +-Wformat-truncation with W=1. Looking closely, It doesn't need to be 255B, +hence this patch reduces the size to 32B which should be more than enough +to host the string: "ICOSQ: 0x%x, ". + +While here, add a missing space in the formatted string. + +This fixes the following build warning: + +$ KCFLAGS='-Wall -Werror' +$ make O=/tmp/kbuild/linux W=1 -s -j12 drivers/net/ethernet/mellanox/mlx5/core/ + +drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c: In function 'mlx5e_reporter_rx_timeout': +drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c:718:56: +error: ', CQ: 0x' directive output may be truncated writing 8 bytes into a region of size between 0 and 255 [-Werror=format-truncation=] + 718 | "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", + | ^~~~~~~~ +drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c:717:9: note: 'snprintf' output between 43 and 322 bytes into a destination of size 288 + 717 | snprintf(err_str, sizeof(err_str), + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 718 | "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 719 | rq->ix, icosq_str, rq->rqn, rq->cq.mcq.cqn); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixes: 521f31af004a ("net/mlx5e: Allow RQ outside of channel context") +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d4ab2e97dcfbcd748ae71761a9d8e5e41cc732c +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-14-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +index e8eea9ffd5eb6..03b119a434bc9 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +@@ -702,11 +702,11 @@ static int mlx5e_rx_reporter_dump(struct devlink_health_reporter *reporter, + + void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) + { +- char icosq_str[MLX5E_REPORTER_PER_Q_MAX_LEN] = {}; + char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN]; + struct mlx5e_icosq *icosq = rq->icosq; + struct mlx5e_priv *priv = rq->priv; + struct mlx5e_err_ctx err_ctx = {}; ++ char icosq_str[32] = {}; + + err_ctx.ctx = rq; + err_ctx.recover = mlx5e_rx_reporter_timeout_recover; +@@ -715,7 +715,7 @@ void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) + if (icosq) + snprintf(icosq_str, sizeof(icosq_str), "ICOSQ: 0x%x, ", icosq->sqn); + snprintf(err_str, sizeof(err_str), +- "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", ++ "RX timeout on channel: %d, %s RQ: 0x%x, CQ: 0x%x", + rq->ix, icosq_str, rq->rqn, rq->cq.mcq.cqn); + + mlx5e_health_report(priv, priv->rx_reporter, err_str, &err_ctx); +-- +2.42.0 + diff --git a/queue-6.5/net-mlx5e-update-doorbell-for-port-timestamping-cq-b.patch b/queue-6.5/net-mlx5e-update-doorbell-for-port-timestamping-cq-b.patch new file mode 100644 index 00000000000..5be3b3a73ad --- /dev/null +++ b/queue-6.5/net-mlx5e-update-doorbell-for-port-timestamping-cq-b.patch @@ -0,0 +1,97 @@ +From e3597987a9a91ced0fb8bcda8a2935adb601b21f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Nov 2023 13:58:42 -0800 +Subject: net/mlx5e: Update doorbell for port timestamping CQ before the + software counter + +From: Rahul Rameshbabu + +[ Upstream commit 92214be5979c0961a471b7eaaaeacab41bdf456c ] + +Previously, mlx5e_ptp_poll_ts_cq would update the device doorbell with the +incremented consumer index after the relevant software counters in the +kernel were updated. In the mlx5e_sq_xmit_wqe context, this would lead to +either overrunning the device CQ or exceeding the expected software buffer +size in the device CQ if the device CQ size was greater than the software +buffer size. Update the relevant software counter only after updating the +device CQ consumer index in the port timestamping napi_poll context. + +Log: + mlx5_core 0000:08:00.0: cq_err_event_notifier:517:(pid 0): CQ error on CQN 0x487, syndrome 0x1 + mlx5_core 0000:08:00.0 eth2: mlx5e_cq_error_event: cqn=0x000487 event=0x04 + +Fixes: 1880bc4e4a96 ("net/mlx5e: Add TX port timestamp support") +Signed-off-by: Rahul Rameshbabu +Signed-off-by: Saeed Mahameed +Link: https://lore.kernel.org/r/20231114215846.5902-12-saeed@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 20 +++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +index bb11e644d24f7..af3928eddafd1 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +@@ -177,6 +177,8 @@ static void mlx5e_ptpsq_mark_ts_cqes_undelivered(struct mlx5e_ptpsq *ptpsq, + + static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, + struct mlx5_cqe64 *cqe, ++ u8 *md_buff, ++ u8 *md_buff_sz, + int budget) + { + struct mlx5e_ptp_port_ts_cqe_list *pending_cqe_list = ptpsq->ts_cqe_pending_list; +@@ -211,19 +213,24 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, + mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp); + out: + napi_consume_skb(skb, budget); +- mlx5e_ptp_metadata_fifo_push(&ptpsq->metadata_freelist, metadata_id); ++ md_buff[*md_buff_sz++] = metadata_id; + if (unlikely(mlx5e_ptp_metadata_map_unhealthy(&ptpsq->metadata_map)) && + !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) + queue_work(ptpsq->txqsq.priv->wq, &ptpsq->report_unhealthy_work); + } + +-static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) ++static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int napi_budget) + { + struct mlx5e_ptpsq *ptpsq = container_of(cq, struct mlx5e_ptpsq, ts_cq); +- struct mlx5_cqwq *cqwq = &cq->wq; ++ int budget = min(napi_budget, MLX5E_TX_CQ_POLL_BUDGET); ++ u8 metadata_buff[MLX5E_TX_CQ_POLL_BUDGET]; ++ u8 metadata_buff_sz = 0; ++ struct mlx5_cqwq *cqwq; + struct mlx5_cqe64 *cqe; + int work_done = 0; + ++ cqwq = &cq->wq; ++ + if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state))) + return false; + +@@ -234,7 +241,8 @@ static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) + do { + mlx5_cqwq_pop(cqwq); + +- mlx5e_ptp_handle_ts_cqe(ptpsq, cqe, budget); ++ mlx5e_ptp_handle_ts_cqe(ptpsq, cqe, ++ metadata_buff, &metadata_buff_sz, napi_budget); + } while ((++work_done < budget) && (cqe = mlx5_cqwq_get_cqe(cqwq))); + + mlx5_cqwq_update_db_record(cqwq); +@@ -242,6 +250,10 @@ static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) + /* ensure cq space is freed before enabling more cqes */ + wmb(); + ++ while (metadata_buff_sz > 0) ++ mlx5e_ptp_metadata_fifo_push(&ptpsq->metadata_freelist, ++ metadata_buff[--metadata_buff_sz]); ++ + mlx5e_txqsq_wake(&ptpsq->txqsq); + + return work_done == budget; +-- +2.42.0 + diff --git a/queue-6.5/net-mvneta-fix-calls-to-page_pool_get_stats.patch b/queue-6.5/net-mvneta-fix-calls-to-page_pool_get_stats.patch new file mode 100644 index 00000000000..66d46180ff4 --- /dev/null +++ b/queue-6.5/net-mvneta-fix-calls-to-page_pool_get_stats.patch @@ -0,0 +1,159 @@ +From f8e4592b74165e68dfe2fc47917b6fde170701a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Nov 2023 05:41:12 +0100 +Subject: net: mvneta: fix calls to page_pool_get_stats + +From: Sven Auhagen + +[ Upstream commit ca8add922f9c7f6e2e3c71039da8e0dcc64b87ed ] + +Calling page_pool_get_stats in the mvneta driver without checks +leads to kernel crashes. +First the page pool is only available if the bm is not used. +The page pool is also not allocated when the port is stopped. +It can also be not allocated in case of errors. + +The current implementation leads to the following crash calling +ethstats on a port that is down or when calling it at the wrong moment: + +ble to handle kernel NULL pointer dereference at virtual address 00000070 +[00000070] *pgd=00000000 +Internal error: Oops: 5 [#1] SMP ARM +Hardware name: Marvell Armada 380/385 (Device Tree) +PC is at page_pool_get_stats+0x18/0x1cc +LR is at mvneta_ethtool_get_stats+0xa0/0xe0 [mvneta] +pc : [] lr : [] psr: a0000013 +sp : f1439d48 ip : f1439dc0 fp : 0000001d +r10: 00000100 r9 : c4816b80 r8 : f0d75150 +r7 : bf0b400c r6 : c238f000 r5 : 00000000 r4 : f1439d68 +r3 : c2091040 r2 : ffffffd8 r1 : f1439d68 r0 : 00000000 +Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none +Control: 10c5387d Table: 066b004a DAC: 00000051 +Register r0 information: NULL pointer +Register r1 information: 2-page vmalloc region starting at 0xf1438000 allocated at kernel_clone+0x9c/0x390 +Register r2 information: non-paged memory +Register r3 information: slab kmalloc-2k start c2091000 pointer offset 64 size 2048 +Register r4 information: 2-page vmalloc region starting at 0xf1438000 allocated at kernel_clone+0x9c/0x390 +Register r5 information: NULL pointer +Register r6 information: slab kmalloc-cg-4k start c238f000 pointer offset 0 size 4096 +Register r7 information: 15-page vmalloc region starting at 0xbf0a8000 allocated at load_module+0xa30/0x219c +Register r8 information: 1-page vmalloc region starting at 0xf0d75000 allocated at ethtool_get_stats+0x138/0x208 +Register r9 information: slab task_struct start c4816b80 pointer offset 0 +Register r10 information: non-paged memory +Register r11 information: non-paged memory +Register r12 information: 2-page vmalloc region starting at 0xf1438000 allocated at kernel_clone+0x9c/0x390 +Process snmpd (pid: 733, stack limit = 0x38de3a88) +Stack: (0xf1439d48 to 0xf143a000) +9d40: 000000c0 00000001 c238f000 bf0b400c f0d75150 c4816b80 +9d60: 00000100 bf0a98d8 00000000 00000000 00000000 00000000 00000000 00000000 +9d80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +9da0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +9dc0: 00000dc0 5335509c 00000035 c238f000 bf0b2214 01067f50 f0d75000 c0b9b9c8 +9de0: 0000001d 00000035 c2212094 5335509c c4816b80 c238f000 c5ad6e00 01067f50 +9e00: c1b0be80 c4816b80 00014813 c0b9d7f0 00000000 00000000 0000001d 0000001d +9e20: 00000000 00001200 00000000 00000000 c216ed90 c73943b8 00000000 00000000 +9e40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +9e60: 00000000 c0ad9034 00000000 00000000 00000000 00000000 00000000 00000000 +9e80: 00000000 00000000 00000000 5335509c c1b0be80 f1439ee4 00008946 c1b0be80 +9ea0: 01067f50 f1439ee3 00000000 00000046 b6d77ae0 c0b383f0 00008946 becc83e8 +9ec0: c1b0be80 00000051 0000000b c68ca480 c7172d00 c0ad8ff0 f1439ee3 cf600e40 +9ee0: 01600e40 32687465 00000000 00000000 00000000 01067f50 00000000 00000000 +9f00: 00000000 5335509c 00008946 00008946 00000000 c68ca480 becc83e8 c05e2de0 +9f20: f1439fb0 c03002f0 00000006 5ac3c35a c4816b80 00000006 b6d77ae0 c030caf0 +9f40: c4817350 00000014 f1439e1c 0000000c 00000000 00000051 01000000 00000014 +9f60: 00003fec f1439edc 00000001 c0372abc b6d77ae0 c0372abc cf600e40 5335509c +9f80: c21e6800 01015c9c 0000000b 00008946 00000036 c03002f0 c4816b80 00000036 +9fa0: b6d77ae0 c03000c0 01015c9c 0000000b 0000000b 00008946 becc83e8 00000000 +9fc0: 01015c9c 0000000b 00008946 00000036 00000035 010678a0 b6d797ec b6d77ae0 +9fe0: b6dbf738 becc838c b6d186d7 b6baa858 40000030 0000000b 00000000 00000000 + page_pool_get_stats from mvneta_ethtool_get_stats+0xa0/0xe0 [mvneta] + mvneta_ethtool_get_stats [mvneta] from ethtool_get_stats+0x154/0x208 + ethtool_get_stats from dev_ethtool+0xf48/0x2480 + dev_ethtool from dev_ioctl+0x538/0x63c + dev_ioctl from sock_ioctl+0x49c/0x53c + sock_ioctl from sys_ioctl+0x134/0xbd8 + sys_ioctl from ret_fast_syscall+0x0/0x1c +Exception stack(0xf1439fa8 to 0xf1439ff0) +9fa0: 01015c9c 0000000b 0000000b 00008946 becc83e8 00000000 +9fc0: 01015c9c 0000000b 00008946 00000036 00000035 010678a0 b6d797ec b6d77ae0 +9fe0: b6dbf738 becc838c b6d186d7 b6baa858 +Code: e28dd004 e1a05000 e2514000 0a00006a (e5902070) + +This commit adds the proper checks before calling page_pool_get_stats. + +Fixes: b3fc79225f05 ("net: mvneta: add support for page_pool_get_stats") +Signed-off-by: Sven Auhagen +Reported-by: Paulo Da Silva +Acked-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/mvneta.c | 28 +++++++++++++++++++-------- + 1 file changed, 20 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index acf4f6ba73a6f..f4692a8726b1c 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -4790,14 +4790,17 @@ static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, + u8 *data) + { + if (sset == ETH_SS_STATS) { ++ struct mvneta_port *pp = netdev_priv(netdev); + int i; + + for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) + memcpy(data + i * ETH_GSTRING_LEN, + mvneta_statistics[i].name, ETH_GSTRING_LEN); + +- data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); +- page_pool_ethtool_stats_get_strings(data); ++ if (!pp->bm_priv) { ++ data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); ++ page_pool_ethtool_stats_get_strings(data); ++ } + } + } + +@@ -4915,8 +4918,10 @@ static void mvneta_ethtool_pp_stats(struct mvneta_port *pp, u64 *data) + struct page_pool_stats stats = {}; + int i; + +- for (i = 0; i < rxq_number; i++) +- page_pool_get_stats(pp->rxqs[i].page_pool, &stats); ++ for (i = 0; i < rxq_number; i++) { ++ if (pp->rxqs[i].page_pool) ++ page_pool_get_stats(pp->rxqs[i].page_pool, &stats); ++ } + + page_pool_ethtool_stats_get(data, &stats); + } +@@ -4932,14 +4937,21 @@ static void mvneta_ethtool_get_stats(struct net_device *dev, + for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) + *data++ = pp->ethtool_stats[i]; + +- mvneta_ethtool_pp_stats(pp, data); ++ if (!pp->bm_priv) ++ mvneta_ethtool_pp_stats(pp, data); + } + + static int mvneta_ethtool_get_sset_count(struct net_device *dev, int sset) + { +- if (sset == ETH_SS_STATS) +- return ARRAY_SIZE(mvneta_statistics) + +- page_pool_ethtool_stats_get_count(); ++ if (sset == ETH_SS_STATS) { ++ int count = ARRAY_SIZE(mvneta_statistics); ++ struct mvneta_port *pp = netdev_priv(dev); ++ ++ if (!pp->bm_priv) ++ count += page_pool_ethtool_stats_get_count(); ++ ++ return count; ++ } + + return -EOPNOTSUPP; + } +-- +2.42.0 + diff --git a/queue-6.5/net-sched-do-not-offload-flows-with-a-helper-in-act_.patch b/queue-6.5/net-sched-do-not-offload-flows-with-a-helper-in-act_.patch new file mode 100644 index 00000000000..ef0b89080e7 --- /dev/null +++ b/queue-6.5/net-sched-do-not-offload-flows-with-a-helper-in-act_.patch @@ -0,0 +1,90 @@ +From 630d7f105ff6d370cb1ebea1c68d01cac9a8ee1c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 12:53:28 -0500 +Subject: net: sched: do not offload flows with a helper in act_ct + +From: Xin Long + +[ Upstream commit 7cd5af0e937a197295f3aa3721031f0fbae49cff ] + +There is no hardware supporting ct helper offload. However, prior to this +patch, a flower filter with a helper in the ct action can be successfully +set into the HW, for example (eth1 is a bnxt NIC): + + # tc qdisc add dev eth1 ingress_block 22 ingress + # tc filter add block 22 proto ip flower skip_sw ip_proto tcp \ + dst_port 21 ct_state -trk action ct helper ipv4-tcp-ftp + # tc filter show dev eth1 ingress + + filter block 22 protocol ip pref 49152 flower chain 0 handle 0x1 + eth_type ipv4 + ip_proto tcp + dst_port 21 + ct_state -trk + skip_sw + in_hw in_hw_count 1 <---- + action order 1: ct zone 0 helper ipv4-tcp-ftp pipe + index 2 ref 1 bind 1 + used_hw_stats delayed + +This might cause the flower filter not to work as expected in the HW. + +This patch avoids this problem by simply returning -EOPNOTSUPP in +tcf_ct_offload_act_setup() to not allow to offload flows with a helper +in act_ct. + +Fixes: a21b06e73191 ("net: sched: add helper support in act_ct") +Signed-off-by: Xin Long +Reviewed-by: Jamal Hadi Salim +Link: https://lore.kernel.org/r/f8685ec7702c4a448a1371a8b34b43217b583b9d.1699898008.git.lucien.xin@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/net/tc_act/tc_ct.h | 9 +++++++++ + net/sched/act_ct.c | 3 +++ + 2 files changed, 12 insertions(+) + +diff --git a/include/net/tc_act/tc_ct.h b/include/net/tc_act/tc_ct.h +index b24ea2d9400ba..1dc2f827d0bcf 100644 +--- a/include/net/tc_act/tc_ct.h ++++ b/include/net/tc_act/tc_ct.h +@@ -57,6 +57,11 @@ static inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a) + return to_ct_params(a)->nf_ft; + } + ++static inline struct nf_conntrack_helper *tcf_ct_helper(const struct tc_action *a) ++{ ++ return to_ct_params(a)->helper; ++} ++ + #else + static inline uint16_t tcf_ct_zone(const struct tc_action *a) { return 0; } + static inline int tcf_ct_action(const struct tc_action *a) { return 0; } +@@ -64,6 +69,10 @@ static inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a) + { + return NULL; + } ++static inline struct nf_conntrack_helper *tcf_ct_helper(const struct tc_action *a) ++{ ++ return NULL; ++} + #endif /* CONFIG_NF_CONNTRACK */ + + #if IS_ENABLED(CONFIG_NET_ACT_CT) +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index d131750663c3c..ea05d0b2df68a 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -1534,6 +1534,9 @@ static int tcf_ct_offload_act_setup(struct tc_action *act, void *entry_data, + if (bind) { + struct flow_action_entry *entry = entry_data; + ++ if (tcf_ct_helper(act)) ++ return -EOPNOTSUPP; ++ + entry->id = FLOW_ACTION_CT; + entry->ct.action = tcf_ct_action(act); + entry->ct.zone = tcf_ct_zone(act); +-- +2.42.0 + diff --git a/queue-6.5/net-set-sock_rcu_free-before-inserting-socket-into-h.patch b/queue-6.5/net-set-sock_rcu_free-before-inserting-socket-into-h.patch new file mode 100644 index 00000000000..6346f9ffcb2 --- /dev/null +++ b/queue-6.5/net-set-sock_rcu_free-before-inserting-socket-into-h.patch @@ -0,0 +1,88 @@ +From c80816c24774a0edb1339820e391d3bee86ebdb1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Nov 2023 13:13:25 -0800 +Subject: net: set SOCK_RCU_FREE before inserting socket into hashtable + +From: Stanislav Fomichev + +[ Upstream commit 871019b22d1bcc9fab2d1feba1b9a564acbb6e99 ] + +We've started to see the following kernel traces: + + WARNING: CPU: 83 PID: 0 at net/core/filter.c:6641 sk_lookup+0x1bd/0x1d0 + + Call Trace: + + __bpf_skc_lookup+0x10d/0x120 + bpf_sk_lookup+0x48/0xd0 + bpf_sk_lookup_tcp+0x19/0x20 + bpf_prog_+0x37c/0x16a3 + cls_bpf_classify+0x205/0x2e0 + tcf_classify+0x92/0x160 + __netif_receive_skb_core+0xe52/0xf10 + __netif_receive_skb_list_core+0x96/0x2b0 + napi_complete_done+0x7b5/0xb70 + _poll+0x94/0xb0 + net_rx_action+0x163/0x1d70 + __do_softirq+0xdc/0x32e + asm_call_irq_on_stack+0x12/0x20 + + do_softirq_own_stack+0x36/0x50 + do_softirq+0x44/0x70 + +__inet_hash can race with lockless (rcu) readers on the other cpus: + + __inet_hash + __sk_nulls_add_node_rcu + <- (bpf triggers here) + sock_set_flag(SOCK_RCU_FREE) + +Let's move the SOCK_RCU_FREE part up a bit, before we are inserting +the socket into hashtables. Note, that the race is really harmless; +the bpf callers are handling this situation (where listener socket +doesn't have SOCK_RCU_FREE set) correctly, so the only +annoyance is a WARN_ONCE. + +More details from Eric regarding SOCK_RCU_FREE timeline: + +Commit 3b24d854cb35 ("tcp/dccp: do not touch listener sk_refcnt under +synflood") added SOCK_RCU_FREE. At that time, the precise location of +sock_set_flag(sk, SOCK_RCU_FREE) did not matter, because the thread calling +__inet_hash() owns a reference on sk. SOCK_RCU_FREE was only tested +at dismantle time. + +Commit 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") +started checking SOCK_RCU_FREE _after_ the lookup to infer whether +the refcount has been taken care of. + +Fixes: 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") +Reviewed-by: Eric Dumazet +Signed-off-by: Stanislav Fomichev +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_hashtables.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 60cffabfd4788..c8c2704a320f1 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -731,12 +731,12 @@ int __inet_hash(struct sock *sk, struct sock *osk) + if (err) + goto unlock; + } ++ sock_set_flag(sk, SOCK_RCU_FREE); + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && + sk->sk_family == AF_INET6) + __sk_nulls_add_node_tail_rcu(sk, &ilb2->nulls_head); + else + __sk_nulls_add_node_rcu(sk, &ilb2->nulls_head); +- sock_set_flag(sk, SOCK_RCU_FREE); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + unlock: + spin_unlock(&ilb2->lock); +-- +2.42.0 + diff --git a/queue-6.5/net-sfp-add-quirk-for-fiberstone-gpon-onu-34-20bi.patch b/queue-6.5/net-sfp-add-quirk-for-fiberstone-gpon-onu-34-20bi.patch new file mode 100644 index 00000000000..af018d985e5 --- /dev/null +++ b/queue-6.5/net-sfp-add-quirk-for-fiberstone-gpon-onu-34-20bi.patch @@ -0,0 +1,42 @@ +From 5cc72d679f1af08b9ec7236163e1c08552aa89ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 14:47:20 +0200 +Subject: net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI + +From: Christian Marangi + +[ Upstream commit d387e34fec407f881fdf165b5d7ec128ebff362f ] + +Fiberstone GPON-ONU-34-20B can operate at 2500base-X, but report 1.2GBd +NRZ in their EEPROM. + +The module also require the ignore tx fault fixup similar to Huawei MA5671A +as it gets disabled on error messages with serial redirection enabled. + +Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20230919124720.8210-1-ansuelsmth@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/phy/sfp.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index d855a18308d78..338b9769d91a1 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -452,6 +452,11 @@ static const struct sfp_quirk sfp_quirks[] = { + // Rollball protocol to talk to the PHY. + SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt), + ++ // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd ++ // NRZ in their EEPROM ++ SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex, ++ sfp_fixup_ignore_tx_fault), ++ + SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp), + + // HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports +-- +2.42.0 + diff --git a/queue-6.5/net-sfp-add-quirk-for-fs-s-2.5g-copper-sfp.patch b/queue-6.5/net-sfp-add-quirk-for-fs-s-2.5g-copper-sfp.patch new file mode 100644 index 00000000000..5371df8205e --- /dev/null +++ b/queue-6.5/net-sfp-add-quirk-for-fs-s-2.5g-copper-sfp.patch @@ -0,0 +1,39 @@ +From 92907131eb873fae2bf76ec3fe914307866ed3de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 13:30:59 +0530 +Subject: net: sfp: add quirk for FS's 2.5G copper SFP + +From: Raju Lakkaraju + +[ Upstream commit e27aca3760c08b7b05aea71068bd609aa93e7b35 ] + +Add a quirk for a copper SFP that identifies itself as "FS" "SFP-2.5G-T". +This module's PHY is inaccessible, and can only run at 2500base-X with the +host without negotiation. Add a quirk to enable the 2500base-X interface mode +with 2500base-T support and disable auto negotiation. + +Signed-off-by: Raju Lakkaraju +Link: https://lore.kernel.org/r/20230925080059.266240-1-Raju.Lakkaraju@microchip.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/phy/sfp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index 338b9769d91a1..f411ded5344a8 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -468,6 +468,9 @@ static const struct sfp_quirk sfp_quirks[] = { + SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex, + sfp_fixup_ignore_tx_fault), + ++ // FS 2.5G Base-T ++ SFP_QUIRK_M("FS", "SFP-2.5G-T", sfp_quirk_oem_2_5g), ++ + // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report + // 2500MBd NRZ in their EEPROM + SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex), +-- +2.42.0 + diff --git a/queue-6.5/net-stmmac-avoid-rx-queue-overrun.patch b/queue-6.5/net-stmmac-avoid-rx-queue-overrun.patch new file mode 100644 index 00000000000..3ad4646305b --- /dev/null +++ b/queue-6.5/net-stmmac-avoid-rx-queue-overrun.patch @@ -0,0 +1,41 @@ +From 34c80deb95f2aa0a1a3a73f11183df0f41d79dfd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 19:42:50 +0200 +Subject: net: stmmac: avoid rx queue overrun + +From: Baruch Siach + +[ Upstream commit b6cb4541853c7ee512111b0e7ddf3cb66c99c137 ] + +dma_rx_size can be set as low as 64. Rx budget might be higher than +that. Make sure to not overrun allocated rx buffers when budget is +larger. + +Leave one descriptor unused to avoid wrap around of 'dirty_rx' vs +'cur_rx'. + +Signed-off-by: Baruch Siach +Reviewed-by: Serge Semin +Fixes: 47dd7a540b8a ("net: add support for STMicroelectronics Ethernet controllers.") +Link: https://lore.kernel.org/r/d95413e44c97d4692e72cec13a75f894abeb6998.1699897370.git.baruch@tkos.co.il +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 7f9b02bb22a30..86ff015fba354 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5223,6 +5223,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) + + dma_dir = page_pool_get_dma_dir(rx_q->page_pool); + buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; ++ limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); + + if (netif_msg_rx_status(priv)) { + void *rx_head; +-- +2.42.0 + diff --git a/queue-6.5/net-stmmac-fix-rx-budget-limit-check.patch b/queue-6.5/net-stmmac-fix-rx-budget-limit-check.patch new file mode 100644 index 00000000000..6f683b13468 --- /dev/null +++ b/queue-6.5/net-stmmac-fix-rx-budget-limit-check.patch @@ -0,0 +1,46 @@ +From 89643f1cf9f750a857448711ed1966c8a74fb519 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 19:42:49 +0200 +Subject: net: stmmac: fix rx budget limit check + +From: Baruch Siach + +[ Upstream commit fa02de9e75889915b554eda1964a631fd019973b ] + +The while loop condition verifies 'count < limit'. Neither value change +before the 'count >= limit' check. As is this check is dead code. But +code inspection reveals a code path that modifies 'count' and then goto +'drain_data' and back to 'read_again'. So there is a need to verify +count value sanity after 'read_again'. + +Move 'read_again' up to fix the count limit check. + +Fixes: ec222003bd94 ("net: stmmac: Prepare to add Split Header support") +Signed-off-by: Baruch Siach +Reviewed-by: Serge Semin +Link: https://lore.kernel.org/r/d9486296c3b6b12ab3a0515fcd47d56447a07bfc.1699897370.git.baruch@tkos.co.il +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index e840cadb2d75a..7f9b02bb22a30 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5258,10 +5258,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + buf2_len = 0; + entry = next_entry; +-- +2.42.0 + diff --git a/queue-6.5/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch b/queue-6.5/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch new file mode 100644 index 00000000000..f31231596cd --- /dev/null +++ b/queue-6.5/netfilter-nf_conntrack_bridge-initialize-err-to-0.patch @@ -0,0 +1,43 @@ +From 41bfdf0260b1f295eb30764666c6b8fb9e7d1cc2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Nov 2023 11:20:18 +0800 +Subject: netfilter: nf_conntrack_bridge: initialize err to 0 + +From: Linkui Xiao + +[ Upstream commit a44af08e3d4d7566eeea98d7a29fe06e7b9de944 ] + +K2CI reported a problem: + + consume_skb(skb); + return err; +[nf_br_ip_fragment() error] uninitialized symbol 'err'. + +err is not initialized, because returning 0 is expected, initialize err +to 0. + +Fixes: 3c171f496ef5 ("netfilter: bridge: add connection tracking system") +Reported-by: k2ci +Signed-off-by: Linkui Xiao +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/bridge/netfilter/nf_conntrack_bridge.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c +index 71056ee847736..0fcf357ea7ad3 100644 +--- a/net/bridge/netfilter/nf_conntrack_bridge.c ++++ b/net/bridge/netfilter/nf_conntrack_bridge.c +@@ -37,7 +37,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, + ktime_t tstamp = skb->tstamp; + struct ip_frag_state state; + struct iphdr *iph; +- int err; ++ int err = 0; + + /* for offloaded checksums cleanup checksum before fragmentation */ + if (skb->ip_summed == CHECKSUM_PARTIAL && +-- +2.42.0 + diff --git a/queue-6.5/netfilter-nf_tables-bogus-enoent-when-destroying-ele.patch b/queue-6.5/netfilter-nf_tables-bogus-enoent-when-destroying-ele.patch new file mode 100644 index 00000000000..69e0848f833 --- /dev/null +++ b/queue-6.5/netfilter-nf_tables-bogus-enoent-when-destroying-ele.patch @@ -0,0 +1,47 @@ +From 624364678b6d30a15efac83a5a682e75ab93d483 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 20:34:56 +0100 +Subject: netfilter: nf_tables: bogus ENOENT when destroying element which does + not exist + +From: Pablo Neira Ayuso + +[ Upstream commit a7d5a955bfa854ac6b0c53aaf933394b4e6139e4 ] + +destroy element command bogusly reports ENOENT in case a set element +does not exist. ENOENT errors are skipped, however, err is still set +and propagated to userspace. + + # nft destroy element ip raw BLACKLIST { 1.2.3.4 } + Error: Could not process rule: No such file or directory + destroy element ip raw BLACKLIST { 1.2.3.4 } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Fixes: f80a612dd77c ("netfilter: nf_tables: add support to destroy operation") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 8776266ba1532..398a1bcc6ea61 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -7202,10 +7202,11 @@ static int nf_tables_delsetelem(struct sk_buff *skb, + + if (err < 0) { + NL_SET_BAD_ATTR(extack, attr); +- break; ++ return err; + } + } +- return err; ++ ++ return 0; + } + + /* +-- +2.42.0 + diff --git a/queue-6.5/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch b/queue-6.5/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch new file mode 100644 index 00000000000..dd8737ed093 --- /dev/null +++ b/queue-6.5/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch @@ -0,0 +1,91 @@ +From cbead70063f4f846db338f725715284a18f4ef0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Nov 2023 09:42:51 +0300 +Subject: netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval() + +From: Dan Carpenter + +[ Upstream commit c301f0981fdd3fd1ffac6836b423c4d7a8e0eb63 ] + +The problem is in nft_byteorder_eval() where we are iterating through a +loop and writing to dst[0], dst[1], dst[2] and so on... On each +iteration we are writing 8 bytes. But dst[] is an array of u32 so each +element only has space for 4 bytes. That means that every iteration +overwrites part of the previous element. + +I spotted this bug while reviewing commit caf3ef7468f7 ("netfilter: +nf_tables: prevent OOB access in nft_byteorder_eval") which is a related +issue. I think that the reason we have not detected this bug in testing +is that most of time we only write one element. + +Fixes: ce1e7989d989 ("netfilter: nft_byteorder: provide 64bit le/be conversion") +Signed-off-by: Dan Carpenter +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 4 ++-- + net/netfilter/nft_byteorder.c | 5 +++-- + net/netfilter/nft_meta.c | 2 +- + 3 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 7c816359d5a98..75972e211ba12 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -178,9 +178,9 @@ static inline __be32 nft_reg_load_be32(const u32 *sreg) + return *(__force __be32 *)sreg; + } + +-static inline void nft_reg_store64(u32 *dreg, u64 val) ++static inline void nft_reg_store64(u64 *dreg, u64 val) + { +- put_unaligned(val, (u64 *)dreg); ++ put_unaligned(val, dreg); + } + + static inline u64 nft_reg_load64(const u32 *sreg) +diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c +index e596d1a842f70..f6e791a681015 100644 +--- a/net/netfilter/nft_byteorder.c ++++ b/net/netfilter/nft_byteorder.c +@@ -38,13 +38,14 @@ void nft_byteorder_eval(const struct nft_expr *expr, + + switch (priv->size) { + case 8: { ++ u64 *dst64 = (void *)dst; + u64 src64; + + switch (priv->op) { + case NFT_BYTEORDER_NTOH: + for (i = 0; i < priv->len / 8; i++) { + src64 = nft_reg_load64(&src[i]); +- nft_reg_store64(&dst[i], ++ nft_reg_store64(&dst64[i], + be64_to_cpu((__force __be64)src64)); + } + break; +@@ -52,7 +53,7 @@ void nft_byteorder_eval(const struct nft_expr *expr, + for (i = 0; i < priv->len / 8; i++) { + src64 = (__force __u64) + cpu_to_be64(nft_reg_load64(&src[i])); +- nft_reg_store64(&dst[i], src64); ++ nft_reg_store64(&dst64[i], src64); + } + break; + } +diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c +index 8fdc7318c03c7..715484665a907 100644 +--- a/net/netfilter/nft_meta.c ++++ b/net/netfilter/nft_meta.c +@@ -63,7 +63,7 @@ nft_meta_get_eval_time(enum nft_meta_keys key, + { + switch (key) { + case NFT_META_TIME_NS: +- nft_reg_store64(dest, ktime_get_real_ns()); ++ nft_reg_store64((u64 *)dest, ktime_get_real_ns()); + break; + case NFT_META_TIME_DAY: + nft_reg_store8(dest, nft_meta_weekday()); +-- +2.42.0 + diff --git a/queue-6.5/nfsv4.1-fix-handling-nfs4err_delay-when-testing-for-.patch b/queue-6.5/nfsv4.1-fix-handling-nfs4err_delay-when-testing-for-.patch new file mode 100644 index 00000000000..4fd40558c54 --- /dev/null +++ b/queue-6.5/nfsv4.1-fix-handling-nfs4err_delay-when-testing-for-.patch @@ -0,0 +1,54 @@ +From 861435a265f6ddf387d6ca0b86468aed79c46add Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 15:21:16 -0400 +Subject: NFSv4.1: fix handling NFS4ERR_DELAY when testing for session trunking + +From: Olga Kornievskaia + +[ Upstream commit 6bd1a77dc72dea0b0d8b6014f231143984d18f6d ] + +Currently when client sends an EXCHANGE_ID for a possible trunked +connection, for any error that happened, the trunk will be thrown +out. However, an NFS4ERR_DELAY is a transient error that should be +retried instead. + +Fixes: e818bd085baf ("NFSv4.1 remove xprt from xprt_switch if session trunking test fails") +Signed-off-by: Olga Kornievskaia +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4proc.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 5f088e3eeca1d..c710fde58be11 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -8934,6 +8934,7 @@ void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, + + sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED); + ++try_again: + /* Test connection for session trunking. Async exchange_id call */ + task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt); + if (IS_ERR(task)) +@@ -8946,11 +8947,15 @@ void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, + + if (status == 0) + rpc_clnt_xprt_switch_add_xprt(clnt, xprt); +- else if (rpc_clnt_xprt_switch_has_addr(clnt, ++ else if (status != -NFS4ERR_DELAY && rpc_clnt_xprt_switch_has_addr(clnt, + (struct sockaddr *)&xprt->addr)) + rpc_clnt_xprt_switch_remove_xprt(clnt, xprt); + + rpc_put_task(task); ++ if (status == -NFS4ERR_DELAY) { ++ ssleep(1); ++ goto try_again; ++ } + } + EXPORT_SYMBOL_GPL(nfs4_test_session_trunk); + +-- +2.42.0 + diff --git a/queue-6.5/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch b/queue-6.5/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch new file mode 100644 index 00000000000..3a021f17bae --- /dev/null +++ b/queue-6.5/nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch @@ -0,0 +1,48 @@ +From ee6aa3ac09113603fa2b21528d9657c0bd09d259 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 11:04:10 -0400 +Subject: NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO + +From: Olga Kornievskaia + +[ Upstream commit 5cc7688bae7f0757c39c1d3dfdd827b724061067 ] + +If the client is doing pnfs IO and Kerberos is configured and EXCHANGEID +successfully negotiated SP4_MACH_CRED and WRITE/COMMIT are on the +list of state protected operations, then we need to make sure to +choose the DS's rpc_client structure instead of the MDS's one. + +Fixes: fb91fb0ee7b2 ("NFS: Move call to nfs4_state_protect_write() to nfs4_write_setup()") +Signed-off-by: Olga Kornievskaia +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4proc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index c710fde58be11..8374fa230ba5a 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5622,7 +5622,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr, + + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; + nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); +- nfs4_state_protect_write(server->nfs_client, clnt, msg, hdr); ++ nfs4_state_protect_write(hdr->ds_clp ? hdr->ds_clp : server->nfs_client, clnt, msg, hdr); + } + + static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) +@@ -5663,7 +5663,8 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess + data->res.server = server; + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; + nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0); +- nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_COMMIT, clnt, msg); ++ nfs4_state_protect(data->ds_clp ? data->ds_clp : server->nfs_client, ++ NFS_SP4_MACH_CRED_COMMIT, clnt, msg); + } + + static int _nfs4_proc_commit(struct file *dst, struct nfs_commitargs *args, +-- +2.42.0 + diff --git a/queue-6.5/of-address-fix-address-translation-when-address-size.patch b/queue-6.5/of-address-fix-address-translation-when-address-size.patch new file mode 100644 index 00000000000..527c85c5c5a --- /dev/null +++ b/queue-6.5/of-address-fix-address-translation-when-address-size.patch @@ -0,0 +1,128 @@ +From 8f137c97af4f73e8c26ab4a6ce57af18d2bb5095 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 13:02:16 +0200 +Subject: of: address: Fix address translation when address-size is greater + than 2 + +From: Herve Codina + +[ Upstream commit 42604f8eb7ba04b589375049cc76282dad4677d2 ] + +With the recent addition of of_pci_prop_ranges() in commit 407d1a51921e +("PCI: Create device tree node for bridge"), the ranges property can +have a 3 cells child address, a 3 cells parent address and a 2 cells +child size. + +A range item property for a PCI device is filled as follow: + 0 0 + <-- Child --> <-- Parent (PCI definition) --> <- BAR size (64bit) --> + +This allow to translate BAR addresses from the DT. For instance: +pci@0,0 { + #address-cells = <0x03>; + #size-cells = <0x02>; + device_type = "pci"; + compatible = "pci11ab,100", "pciclass,060400", "pciclass,0604"; + ranges = <0x82000000 0x00 0xe8000000 + 0x82000000 0x00 0xe8000000 + 0x00 0x4400000>; + ... + dev@0,0 { + #address-cells = <0x03>; + #size-cells = <0x02>; + compatible = "pci1055,9660", "pciclass,020000", "pciclass,0200"; + /* Translations for BAR0 to BAR5 */ + ranges = <0x00 0x00 0x00 0x82010000 0x00 0xe8000000 0x00 0x2000000 + 0x01 0x00 0x00 0x82010000 0x00 0xea000000 0x00 0x1000000 + 0x02 0x00 0x00 0x82010000 0x00 0xeb000000 0x00 0x800000 + 0x03 0x00 0x00 0x82010000 0x00 0xeb800000 0x00 0x800000 + 0x04 0x00 0x00 0x82010000 0x00 0xec000000 0x00 0x20000 + 0x05 0x00 0x00 0x82010000 0x00 0xec020000 0x00 0x2000>; + ... + pci-ep-bus@0 { + #address-cells = <0x01>; + #size-cells = <0x01>; + compatible = "simple-bus"; + /* Translate 0xe2000000 to BAR0 and 0xe0000000 to BAR1 */ + ranges = <0xe2000000 0x00 0x00 0x00 0x2000000 + 0xe0000000 0x01 0x00 0x00 0x1000000>; + ... + }; + }; +}; + +During the translation process, the "default-flags" map() function is +used to select the matching item in the ranges table and determine the +address offset from this matching item. +This map() function simply calls of_read_number() and when address-size +is greater than 2, the map() function skips the extra high address part +(ie part over 64bit). This lead to a wrong matching item and a wrong +offset computation. +Also during the translation itself, the extra high part related to the +parent address is not present in the translated address. + +Fix the "default-flags" map() and translate() in order to take into +account the child extra high address part in map() and the parent extra +high address part in translate() and so having a correct address +translation for ranges patterns such as the one given in the example +above. + +Signed-off-by: Herve Codina +Link: https://lore.kernel.org/r/20231017110221.189299-2-herve.codina@bootlin.com +Signed-off-by: Rob Herring +Signed-off-by: Sasha Levin +--- + drivers/of/address.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/drivers/of/address.c b/drivers/of/address.c +index e692809ff8227..3219c51777507 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -100,6 +100,32 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr) + return IORESOURCE_MEM; + } + ++static u64 of_bus_default_flags_map(__be32 *addr, const __be32 *range, int na, ++ int ns, int pna) ++{ ++ u64 cp, s, da; ++ ++ /* Check that flags match */ ++ if (*addr != *range) ++ return OF_BAD_ADDR; ++ ++ /* Read address values, skipping high cell */ ++ cp = of_read_number(range + 1, na - 1); ++ s = of_read_number(range + na + pna, ns); ++ da = of_read_number(addr + 1, na - 1); ++ ++ pr_debug("default flags map, cp=%llx, s=%llx, da=%llx\n", cp, s, da); ++ ++ if (da < cp || da >= (cp + s)) ++ return OF_BAD_ADDR; ++ return da - cp; ++} ++ ++static int of_bus_default_flags_translate(__be32 *addr, u64 offset, int na) ++{ ++ /* Keep "flags" part (high cell) in translated address */ ++ return of_bus_default_translate(addr + 1, offset, na - 1); ++} + + #ifdef CONFIG_PCI + static unsigned int of_bus_pci_get_flags(const __be32 *addr) +@@ -374,8 +400,8 @@ static struct of_bus of_busses[] = { + .addresses = "reg", + .match = of_bus_default_flags_match, + .count_cells = of_bus_default_count_cells, +- .map = of_bus_default_map, +- .translate = of_bus_default_translate, ++ .map = of_bus_default_flags_map, ++ .translate = of_bus_default_flags_translate, + .has_flags = true, + .get_flags = of_bus_default_flags_get_flags, + }, +-- +2.42.0 + diff --git a/queue-6.5/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch b/queue-6.5/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch new file mode 100644 index 00000000000..611d93be19b --- /dev/null +++ b/queue-6.5/pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch @@ -0,0 +1,60 @@ +From c1b5160499553ad6ad289cd7a3c05dea6e5bd190 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 14:36:06 +0000 +Subject: PCI: Disable ATS for specific Intel IPU E2000 devices + +From: Bartosz Pawlowski + +[ Upstream commit a18615b1cfc04f00548c60eb9a77e0ce56e848fd ] + +Due to a hardware issue in A and B steppings of Intel IPU E2000, it expects +wrong endianness in ATS invalidation message body. This problem can lead to +outdated translations being returned as valid and finally cause system +instability. + +To prevent such issues, add quirk_intel_e2000_no_ats() to disable ATS for +vulnerable IPU E2000 devices. + +Link: https://lore.kernel.org/r/20230908143606.685930-3-bartosz.pawlowski@intel.com +Signed-off-by: Bartosz Pawlowski +Signed-off-by: Bjorn Helgaas +Reviewed-by: Andy Shevchenko +Reviewed-by: Alexander Lobakin +Signed-off-by: Sasha Levin +--- + drivers/pci/quirks.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index b82f94af2fae4..9fa3c9225bb30 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5552,6 +5552,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats); + /* AMD Raven platform iGPU */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); ++ ++/* ++ * Intel IPU E2000 revisions before C0 implement incorrect endianness ++ * in ATS Invalidate Request message body. Disable ATS for those devices. ++ */ ++static void quirk_intel_e2000_no_ats(struct pci_dev *pdev) ++{ ++ if (pdev->revision < 0x20) ++ quirk_no_ats(pdev); ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats); + #endif /* CONFIG_PCI_ATS */ + + /* Freescale PCIe doesn't support MSI in RC mode */ +-- +2.42.0 + diff --git a/queue-6.5/pci-do-error-check-on-own-line-to-split-long-if-cond.patch b/queue-6.5/pci-do-error-check-on-own-line-to-split-long-if-cond.patch new file mode 100644 index 00000000000..a4de6d3489d --- /dev/null +++ b/queue-6.5/pci-do-error-check-on-own-line-to-split-long-if-cond.patch @@ -0,0 +1,109 @@ +From 3bd12fc15a72575baac37602158c0ce531c8e3d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 15:53:52 +0300 +Subject: PCI: Do error check on own line to split long "if" conditions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit d15f18053e5cc5576af9e7eef0b2a91169b6326d ] + +Placing PCI error code check inside "if" condition usually results in need +to split lines. Combined with additional conditions the "if" condition +becomes messy. + +Convert to the usual error handling pattern with an additional variable to +improve code readability. In addition, reverse the logic in +pci_find_vsec_capability() to get rid of &&. + +No functional changes intended. + +Link: https://lore.kernel.org/r/20230911125354.25501-5-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +[bhelgaas: PCI_POSSIBLE_ERROR()] +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/pci.c | 9 ++++++--- + drivers/pci/probe.c | 6 +++--- + drivers/pci/quirks.c | 6 +++--- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 702fe577089b4..3cd907eb67b74 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -732,15 +732,18 @@ u16 pci_find_vsec_capability(struct pci_dev *dev, u16 vendor, int cap) + { + u16 vsec = 0; + u32 header; ++ int ret; + + if (vendor != dev->vendor) + return 0; + + while ((vsec = pci_find_next_ext_capability(dev, vsec, + PCI_EXT_CAP_ID_VNDR))) { +- if (pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, +- &header) == PCIBIOS_SUCCESSFUL && +- PCI_VNDR_HEADER_ID(header) == cap) ++ ret = pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header); ++ if (ret != PCIBIOS_SUCCESSFUL) ++ continue; ++ ++ if (PCI_VNDR_HEADER_ID(header) == cap) + return vsec; + } + +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index 24a83cf5ace8c..cd08d39fdb1ff 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -1653,15 +1653,15 @@ static void pci_set_removable(struct pci_dev *dev) + static bool pci_ext_cfg_is_aliased(struct pci_dev *dev) + { + #ifdef CONFIG_PCI_QUIRKS +- int pos; ++ int pos, ret; + u32 header, tmp; + + pci_read_config_dword(dev, PCI_VENDOR_ID, &header); + + for (pos = PCI_CFG_SPACE_SIZE; + pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) { +- if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL +- || header != tmp) ++ ret = pci_read_config_dword(dev, pos, &tmp); ++ if ((ret != PCIBIOS_SUCCESSFUL) || (header != tmp)) + return false; + } + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index eb65170b97ff0..e8a051e2d8140 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5383,7 +5383,7 @@ int pci_dev_specific_disable_acs_redir(struct pci_dev *dev) + */ + static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) + { +- int pos, i = 0; ++ int pos, i = 0, ret; + u8 next_cap; + u16 reg16, *cap; + struct pci_cap_saved_state *state; +@@ -5429,8 +5429,8 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) + pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; + + pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE; +- if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) != +- PCIBIOS_SUCCESSFUL || (status == 0xffffffff)) ++ ret = pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status); ++ if ((ret != PCIBIOS_SUCCESSFUL) || (PCI_POSSIBLE_ERROR(status))) + pdev->cfg_size = PCI_CFG_SPACE_SIZE; + + if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP)) +-- +2.42.0 + diff --git a/queue-6.5/pci-dwc-add-dw_pcie_link_set_max_link_width.patch b/queue-6.5/pci-dwc-add-dw_pcie_link_set_max_link_width.patch new file mode 100644 index 00000000000..5de836e1931 --- /dev/null +++ b/queue-6.5/pci-dwc-add-dw_pcie_link_set_max_link_width.patch @@ -0,0 +1,138 @@ +From af7464b447ffed7a0079ea34c4cb603f90ba1e00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 17:56:18 +0900 +Subject: PCI: dwc: Add dw_pcie_link_set_max_link_width() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yoshihiro Shimoda + +[ Upstream commit a9a1bcba90254975d4adbcca53f720318cf81c0c ] + +This is a preparation before adding the Max-Link-width capability +setup which would in its turn complete the max-link-width setup +procedure defined by Synopsys in the HW-manual. + +Seeing there is a max-link-speed setup method defined in the DW PCIe +core driver it would be good to have a similar function for the link +width setup. + +That's why we need to define a dedicated function first from already +implemented but incomplete link-width setting up code. + +Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-3-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: Serge Semin +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.c | 86 ++++++++++---------- + 1 file changed, 41 insertions(+), 45 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c +index 1f2ee71da4da2..d14b4da700eaf 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.c ++++ b/drivers/pci/controller/dwc/pcie-designware.c +@@ -732,6 +732,46 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen) + + } + ++static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes) ++{ ++ u32 lwsc, plc; ++ ++ if (!num_lanes) ++ return; ++ ++ /* Set the number of lanes */ ++ plc = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL); ++ plc &= ~PORT_LINK_FAST_LINK_MODE; ++ plc &= ~PORT_LINK_MODE_MASK; ++ ++ /* Set link width speed control register */ ++ lwsc = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); ++ lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK; ++ switch (num_lanes) { ++ case 1: ++ plc |= PORT_LINK_MODE_1_LANES; ++ lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES; ++ break; ++ case 2: ++ plc |= PORT_LINK_MODE_2_LANES; ++ lwsc |= PORT_LOGIC_LINK_WIDTH_2_LANES; ++ break; ++ case 4: ++ plc |= PORT_LINK_MODE_4_LANES; ++ lwsc |= PORT_LOGIC_LINK_WIDTH_4_LANES; ++ break; ++ case 8: ++ plc |= PORT_LINK_MODE_8_LANES; ++ lwsc |= PORT_LOGIC_LINK_WIDTH_8_LANES; ++ break; ++ default: ++ dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes); ++ return; ++ } ++ dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, plc); ++ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, lwsc); ++} ++ + void dw_pcie_iatu_detect(struct dw_pcie *pci) + { + int max_region, ob, ib; +@@ -1013,49 +1053,5 @@ void dw_pcie_setup(struct dw_pcie *pci) + val |= PORT_LINK_DLL_LINK_EN; + dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); + +- if (!pci->num_lanes) { +- dev_dbg(pci->dev, "Using h/w default number of lanes\n"); +- return; +- } +- +- /* Set the number of lanes */ +- val &= ~PORT_LINK_FAST_LINK_MODE; +- val &= ~PORT_LINK_MODE_MASK; +- switch (pci->num_lanes) { +- case 1: +- val |= PORT_LINK_MODE_1_LANES; +- break; +- case 2: +- val |= PORT_LINK_MODE_2_LANES; +- break; +- case 4: +- val |= PORT_LINK_MODE_4_LANES; +- break; +- case 8: +- val |= PORT_LINK_MODE_8_LANES; +- break; +- default: +- dev_err(pci->dev, "num-lanes %u: invalid value\n", pci->num_lanes); +- return; +- } +- dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); +- +- /* Set link width speed control register */ +- val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); +- val &= ~PORT_LOGIC_LINK_WIDTH_MASK; +- switch (pci->num_lanes) { +- case 1: +- val |= PORT_LOGIC_LINK_WIDTH_1_LANES; +- break; +- case 2: +- val |= PORT_LOGIC_LINK_WIDTH_2_LANES; +- break; +- case 4: +- val |= PORT_LOGIC_LINK_WIDTH_4_LANES; +- break; +- case 8: +- val |= PORT_LOGIC_LINK_WIDTH_8_LANES; +- break; +- } +- dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val); ++ dw_pcie_link_set_max_link_width(pci, pci->num_lanes); + } +-- +2.42.0 + diff --git a/queue-6.5/pci-dwc-add-missing-pci_exp_lnkcap_mlw-handling.patch b/queue-6.5/pci-dwc-add-missing-pci_exp_lnkcap_mlw-handling.patch new file mode 100644 index 00000000000..fd5ca824083 --- /dev/null +++ b/queue-6.5/pci-dwc-add-missing-pci_exp_lnkcap_mlw-handling.patch @@ -0,0 +1,75 @@ +From 7ee7bcd7d6552c27f231ab2a665870919dc9dd91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 17:56:19 +0900 +Subject: PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yoshihiro Shimoda + +[ Upstream commit 89db0793c9f2da265ecb6c1681f899d9af157f37 ] + +Update dw_pcie_link_set_max_link_width() to set PCI_EXP_LNKCAP_MLW. + +In accordance with the DW PCIe RC/EP HW manuals [1,2,3,...] aside with +the PORT_LINK_CTRL_OFF.LINK_CAPABLE and GEN2_CTRL_OFF.NUM_OF_LANES[8:0] +field there is another one which needs to be updated. + +It's LINK_CAPABILITIES_REG.PCIE_CAP_MAX_LINK_WIDTH. If it isn't done at +the very least the maximum link-width capability CSR won't expose the +actual maximum capability. + +[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, + Version 4.60a, March 2015, p.1032 +[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, + Version 4.70a, March 2016, p.1065 +[3] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, + Version 4.90a, March 2016, p.1057 +... +[X] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint, + Version 5.40a, March 2019, p.1396 +[X+1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port, + Version 5.40a, March 2019, p.1266 + +Suggested-by: Serge Semin +Link: https://lore.kernel.org/linux-pci/20231018085631.1121289-4-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Krzysztof Wilczyński +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: Serge Semin +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c +index d14b4da700eaf..8e6f6ac42dc96 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.c ++++ b/drivers/pci/controller/dwc/pcie-designware.c +@@ -734,7 +734,8 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen) + + static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes) + { +- u32 lwsc, plc; ++ u32 lnkcap, lwsc, plc; ++ u8 cap; + + if (!num_lanes) + return; +@@ -770,6 +771,12 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes) + } + dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, plc); + dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, lwsc); ++ ++ cap = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); ++ lnkcap = dw_pcie_readl_dbi(pci, cap + PCI_EXP_LNKCAP); ++ lnkcap &= ~PCI_EXP_LNKCAP_MLW; ++ lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, num_lanes); ++ dw_pcie_writel_dbi(pci, cap + PCI_EXP_LNKCAP, lnkcap); + } + + void dw_pcie_iatu_detect(struct dw_pcie *pci) +-- +2.42.0 + diff --git a/queue-6.5/pci-extract-ats-disabling-to-a-helper-function.patch b/queue-6.5/pci-extract-ats-disabling-to-a-helper-function.patch new file mode 100644 index 00000000000..4257b144d6d --- /dev/null +++ b/queue-6.5/pci-extract-ats-disabling-to-a-helper-function.patch @@ -0,0 +1,60 @@ +From 46ba7661e4ad8dab7314ff3f75eab8bc68d4d0ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 14:36:05 +0000 +Subject: PCI: Extract ATS disabling to a helper function + +From: Bartosz Pawlowski + +[ Upstream commit f18b1137d38c091cc8c16365219f0a1d4a30b3d1 ] + +Introduce quirk_no_ats() helper function to provide a standard way to +disable ATS capability in PCI quirks. + +Suggested-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20230908143606.685930-2-bartosz.pawlowski@intel.com +Signed-off-by: Bartosz Pawlowski +Signed-off-by: Bjorn Helgaas +Reviewed-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + drivers/pci/quirks.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index e8a051e2d8140..b82f94af2fae4 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -5507,6 +5507,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); + + #ifdef CONFIG_PCI_ATS ++static void quirk_no_ats(struct pci_dev *pdev) ++{ ++ pci_info(pdev, "disabling ATS\n"); ++ pdev->ats_cap = 0; ++} ++ + /* + * Some devices require additional driver setup to enable ATS. Don't use + * ATS for those devices as ATS will be enabled before the driver has had a +@@ -5520,14 +5526,10 @@ static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) + (pdev->subsystem_device == 0xce19 || + pdev->subsystem_device == 0xcc10 || + pdev->subsystem_device == 0xcc08)) +- goto no_ats; +- else +- return; ++ quirk_no_ats(pdev); ++ } else { ++ quirk_no_ats(pdev); + } +- +-no_ats: +- pci_info(pdev, "disabling ATS\n"); +- pdev->ats_cap = 0; + } + + /* AMD Stoney platform GPU */ +-- +2.42.0 + diff --git a/queue-6.5/pci-mvebu-use-field_prep-with-link-width.patch b/queue-6.5/pci-mvebu-use-field_prep-with-link-width.patch new file mode 100644 index 00000000000..fece762b207 --- /dev/null +++ b/queue-6.5/pci-mvebu-use-field_prep-with-link-width.patch @@ -0,0 +1,42 @@ +From 44bfe652854f6236c245cc317f0663ee525b51df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:45 +0300 +Subject: PCI: mvebu: Use FIELD_PREP() with Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 408599ec561ad5862cda4f107626009f6fa97a74 ] + +mvebu_pcie_setup_hw() setups the Maximum Link Width field in the Link +Capabilities registers using an open-coded variant of FIELD_PREP() with +a literal in shift. Improve readability by using +FIELD_PREP(PCI_EXP_LNKCAP_MLW, ...). + +Link: https://lore.kernel.org/r/20230919125648.1920-6-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pci-mvebu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c +index c931b1b07b1d8..0cacd58f6c05e 100644 +--- a/drivers/pci/controller/pci-mvebu.c ++++ b/drivers/pci/controller/pci-mvebu.c +@@ -265,7 +265,7 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) + */ + lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP); + lnkcap &= ~PCI_EXP_LNKCAP_MLW; +- lnkcap |= (port->is_x4 ? 4 : 1) << 4; ++ lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, port->is_x4 ? 4 : 1); + mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP); + + /* Disable Root Bridge I/O space, memory space and bus mastering. */ +-- +2.42.0 + diff --git a/queue-6.5/pci-tegra194-use-field_get-field_prep-with-link-widt.patch b/queue-6.5/pci-tegra194-use-field_get-field_prep-with-link-widt.patch new file mode 100644 index 00000000000..8f67452004b --- /dev/null +++ b/queue-6.5/pci-tegra194-use-field_get-field_prep-with-link-widt.patch @@ -0,0 +1,72 @@ +From b1718c42ce4c48eefb84e18ec9bf787b14b718cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:44 +0300 +Subject: PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 759574abd78e3b47ec45bbd31a64e8832cf73f97 ] + +Use FIELD_GET() to extract PCIe Negotiated Link Width field instead of +custom masking and shifting. + +Similarly, change custom code that misleadingly used +PCI_EXP_LNKSTA_NLW_SHIFT to prepare value for PCI_EXP_LNKCAP write +to use FIELD_PREP() with correct field define (PCI_EXP_LNKCAP_MLW). + +Link: https://lore.kernel.org/r/20230919125648.1920-5-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-tegra194.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c +index ccff8cde5cff6..07cb0818a5138 100644 +--- a/drivers/pci/controller/dwc/pcie-tegra194.c ++++ b/drivers/pci/controller/dwc/pcie-tegra194.c +@@ -9,6 +9,7 @@ + * Author: Vidya Sagar + */ + ++#include + #include + #include + #include +@@ -347,8 +348,7 @@ static void apply_bad_link_workaround(struct dw_pcie_rp *pp) + */ + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA); + if (val & PCI_EXP_LNKSTA_LBMS) { +- current_link_width = (val & PCI_EXP_LNKSTA_NLW) >> +- PCI_EXP_LNKSTA_NLW_SHIFT; ++ current_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val); + if (pcie->init_link_width > current_link_width) { + dev_warn(pci->dev, "PCIe link is bad, width reduced\n"); + val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + +@@ -761,8 +761,7 @@ static void tegra_pcie_enable_system_interrupts(struct dw_pcie_rp *pp) + + val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + + PCI_EXP_LNKSTA); +- pcie->init_link_width = (val_w & PCI_EXP_LNKSTA_NLW) >> +- PCI_EXP_LNKSTA_NLW_SHIFT; ++ pcie->init_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val_w); + + val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + + PCI_EXP_LNKCTL); +@@ -921,7 +920,7 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp) + /* Configure Max lane width from DT */ + val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP); + val &= ~PCI_EXP_LNKCAP_MLW; +- val |= (pcie->num_lanes << PCI_EXP_LNKSTA_NLW_SHIFT); ++ val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, pcie->num_lanes); + dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, val); + + /* Clear Slot Clock Configuration bit if SRNS configuration */ +-- +2.42.0 + diff --git a/queue-6.5/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch b/queue-6.5/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch new file mode 100644 index 00000000000..eb2c8f78950 --- /dev/null +++ b/queue-6.5/pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch @@ -0,0 +1,57 @@ +From 6fa3cde4544dde45c6933fd1b4c5e1b348bcd884 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 15:44:28 -0500 +Subject: PCI: Use FIELD_GET() in Sapphire RX 5600 XT Pulse quirk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjorn Helgaas + +[ Upstream commit 04e82fa5951ca66495d7b05665eff673aa3852b4 ] + +Use FIELD_GET() to remove dependences on the field position, i.e., the +shift value. No functional change intended. + +Separate because this isn't as trivial as the other FIELD_GET() changes. + +See 907830b0fc9e ("PCI: Add a REBAR size quirk for Sapphire RX 5600 XT +Pulse") + +Link: https://lore.kernel.org/r/20231010204436.1000644-3-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Reviewed-by: Jonathan Cameron +Reviewed-by: Kuppuswamy Sathyanarayanan +Cc: Nirmoy Das +Signed-off-by: Sasha Levin +--- + drivers/pci/pci.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 2c5662d43df1b..a7793abdd74ee 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -3746,14 +3746,14 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) + return 0; + + pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); +- cap &= PCI_REBAR_CAP_SIZES; ++ cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap); + + /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ + if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && +- bar == 0 && cap == 0x7000) +- cap = 0x3f000; ++ bar == 0 && cap == 0x700) ++ return 0x3f00; + +- return cap >> 4; ++ return cap; + } + EXPORT_SYMBOL(pci_rebar_get_possible_sizes); + +-- +2.42.0 + diff --git a/queue-6.5/pci-use-field_get-to-extract-link-width.patch b/queue-6.5/pci-use-field_get-to-extract-link-width.patch new file mode 100644 index 00000000000..171149c3ca8 --- /dev/null +++ b/queue-6.5/pci-use-field_get-to-extract-link-width.patch @@ -0,0 +1,75 @@ +From e70b8f7e7ae1f49c7be36764934a62fa243a0df6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:46 +0300 +Subject: PCI: Use FIELD_GET() to extract Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit d1f9b39da4a5347150246871325190018cda8cb3 ] + +Use FIELD_GET() to extract PCIe Negotiated and Maximum Link Width fields +instead of custom masking and shifting. + +Link: https://lore.kernel.org/r/20230919125648.1920-7-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +[bhelgaas: drop duplicate include of ] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/pci/pci-sysfs.c | 5 ++--- + drivers/pci/pci.c | 5 ++--- + 2 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c +index ab32a91f287b4..4473773dc2af4 100644 +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -12,7 +12,7 @@ + * Modeled after usb's driverfs.c + */ + +- ++#include + #include + #include + #include +@@ -230,8 +230,7 @@ static ssize_t current_link_width_show(struct device *dev, + if (err) + return -EINVAL; + +- return sysfs_emit(buf, "%u\n", +- (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT); ++ return sysfs_emit(buf, "%u\n", FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat)); + } + static DEVICE_ATTR_RO(current_link_width); + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 3cd907eb67b74..2c5662d43df1b 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -6255,8 +6255,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, + pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta); + + next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS]; +- next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> +- PCI_EXP_LNKSTA_NLW_SHIFT; ++ next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta); + + next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed); + +@@ -6328,7 +6327,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev) + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); + if (lnkcap) +- return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4; ++ return FIELD_GET(PCI_EXP_LNKCAP_MLW, lnkcap); + + return PCIE_LNK_WIDTH_UNKNOWN; + } +-- +2.42.0 + diff --git a/queue-6.5/pds_core-fix-up-some-format-truncation-complaints.patch b/queue-6.5/pds_core-fix-up-some-format-truncation-complaints.patch new file mode 100644 index 00000000000..75fbeac8475 --- /dev/null +++ b/queue-6.5/pds_core-fix-up-some-format-truncation-complaints.patch @@ -0,0 +1,76 @@ +From 3ecb5f1dcf15a8c62f39f838560ee68c05656ec6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 10:32:57 -0800 +Subject: pds_core: fix up some format-truncation complaints + +From: Shannon Nelson + +[ Upstream commit 7c02f6ae676a954216a192612040f9a0cde3adf7 ] + +Our friendly kernel test robot pointed out a couple of potential +string truncation issues. None of which were we worried about, +but can be relatively easily fixed to quiet the complaints. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202310211736.66syyDpp-lkp@intel.com/ +Fixes: 45d76f492938 ("pds_core: set up device and adminq") +Signed-off-by: Shannon Nelson +Link: https://lore.kernel.org/r/20231113183257.71110-3-shannon.nelson@amd.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/pds_core/core.h | 2 +- + drivers/net/ethernet/amd/pds_core/dev.c | 8 ++++++-- + drivers/net/ethernet/amd/pds_core/devlink.c | 2 +- + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h +index e545fafc48196..b1c1f1007b065 100644 +--- a/drivers/net/ethernet/amd/pds_core/core.h ++++ b/drivers/net/ethernet/amd/pds_core/core.h +@@ -15,7 +15,7 @@ + #define PDSC_DRV_DESCRIPTION "AMD/Pensando Core Driver" + + #define PDSC_WATCHDOG_SECS 5 +-#define PDSC_QUEUE_NAME_MAX_SZ 32 ++#define PDSC_QUEUE_NAME_MAX_SZ 16 + #define PDSC_ADMINQ_MIN_LENGTH 16 /* must be a power of two */ + #define PDSC_NOTIFYQ_LENGTH 64 /* must be a power of two */ + #define PDSC_TEARDOWN_RECOVERY false +diff --git a/drivers/net/ethernet/amd/pds_core/dev.c b/drivers/net/ethernet/amd/pds_core/dev.c +index f77cd9f5a2fda..eb178728edba9 100644 +--- a/drivers/net/ethernet/amd/pds_core/dev.c ++++ b/drivers/net/ethernet/amd/pds_core/dev.c +@@ -254,10 +254,14 @@ static int pdsc_identify(struct pdsc *pdsc) + struct pds_core_drv_identity drv = {}; + size_t sz; + int err; ++ int n; + + drv.drv_type = cpu_to_le32(PDS_DRIVER_LINUX); +- snprintf(drv.driver_ver_str, sizeof(drv.driver_ver_str), +- "%s %s", PDS_CORE_DRV_NAME, utsname()->release); ++ /* Catching the return quiets a Wformat-truncation complaint */ ++ n = snprintf(drv.driver_ver_str, sizeof(drv.driver_ver_str), ++ "%s %s", PDS_CORE_DRV_NAME, utsname()->release); ++ if (n > sizeof(drv.driver_ver_str)) ++ dev_dbg(pdsc->dev, "release name truncated, don't care\n"); + + /* Next let's get some info about the device + * We use the devcmd_lock at this level in order to +diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c +index d9607033bbf21..d2abf32b93fe3 100644 +--- a/drivers/net/ethernet/amd/pds_core/devlink.c ++++ b/drivers/net/ethernet/amd/pds_core/devlink.c +@@ -104,7 +104,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, + struct pds_core_fw_list_info fw_list; + struct pdsc *pdsc = devlink_priv(dl); + union pds_core_dev_comp comp; +- char buf[16]; ++ char buf[32]; + int listlen; + int err; + int i; +-- +2.42.0 + diff --git a/queue-6.5/pds_core-use-correct-index-to-mask-irq.patch b/queue-6.5/pds_core-use-correct-index-to-mask-irq.patch new file mode 100644 index 00000000000..c45d91d6785 --- /dev/null +++ b/queue-6.5/pds_core-use-correct-index-to-mask-irq.patch @@ -0,0 +1,67 @@ +From 0d0731a83964fe1aab9d309a5287ac660deb0883 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Nov 2023 10:32:56 -0800 +Subject: pds_core: use correct index to mask irq + +From: Shannon Nelson + +[ Upstream commit 09d4c14c6c5e6e781a3879fed7f8e116a18b8c65 ] + +Use the qcq's interrupt index, not the irq number, to mask +the interrupt. Since the irq number can be out of range from +the number of possible interrupts, we can end up accessing +and potentially scribbling on out-of-range and/or unmapped +memory, making the kernel angry. + + [ 3116.039364] BUG: unable to handle page fault for address: ffffbeea1c3edf84 + [ 3116.047059] #PF: supervisor write access in kernel mode + [ 3116.052895] #PF: error_code(0x0002) - not-present page + [ 3116.058636] PGD 100000067 P4D 100000067 PUD 1001f2067 PMD 10f82e067 PTE 0 + [ 3116.066221] Oops: 0002 [#1] SMP NOPTI + [ 3116.092948] RIP: 0010:iowrite32+0x9/0x76 + [ 3116.190452] Call Trace: + [ 3116.193185] + [ 3116.195430] ? show_trace_log_lvl+0x1d6/0x2f9 + [ 3116.200298] ? show_trace_log_lvl+0x1d6/0x2f9 + [ 3116.205166] ? pdsc_adminq_isr+0x43/0x55 [pds_core] + [ 3116.210618] ? __die_body.cold+0x8/0xa + [ 3116.214806] ? page_fault_oops+0x16d/0x1ac + [ 3116.219382] ? exc_page_fault+0xbe/0x13b + [ 3116.223764] ? asm_exc_page_fault+0x22/0x27 + [ 3116.228440] ? iowrite32+0x9/0x76 + [ 3116.232143] pdsc_adminq_isr+0x43/0x55 [pds_core] + [ 3116.237627] __handle_irq_event_percpu+0x3a/0x184 + [ 3116.243088] handle_irq_event+0x57/0xb0 + [ 3116.247575] handle_edge_irq+0x87/0x225 + [ 3116.252062] __common_interrupt+0x3e/0xbc + [ 3116.256740] common_interrupt+0x7b/0x98 + [ 3116.261216] + [ 3116.263745] + [ 3116.266268] asm_common_interrupt+0x22/0x27 + +Reported-by: Joao Martins +Fixes: 01ba61b55b20 ("pds_core: Add adminq processing and commands") +Signed-off-by: Shannon Nelson +Link: https://lore.kernel.org/r/20231113183257.71110-2-shannon.nelson@amd.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/amd/pds_core/adminq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/amd/pds_core/adminq.c b/drivers/net/ethernet/amd/pds_core/adminq.c +index 045fe133f6ee9..5beadabc21361 100644 +--- a/drivers/net/ethernet/amd/pds_core/adminq.c ++++ b/drivers/net/ethernet/amd/pds_core/adminq.c +@@ -146,7 +146,7 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data) + } + + queue_work(pdsc->wq, &qcq->work); +- pds_core_intr_mask(&pdsc->intr_ctrl[irq], PDS_CORE_INTR_MASK_CLEAR); ++ pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); + + return IRQ_HANDLED; + } +-- +2.42.0 + diff --git a/queue-6.5/perf-core-bail-out-early-if-the-request-aux-area-is-.patch b/queue-6.5/perf-core-bail-out-early-if-the-request-aux-area-is-.patch new file mode 100644 index 00000000000..0e546bd5f73 --- /dev/null +++ b/queue-6.5/perf-core-bail-out-early-if-the-request-aux-area-is-.patch @@ -0,0 +1,76 @@ +From d5eb40bf0355201f5b7583891bb99575d2b8b08c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 08:43:07 +0800 +Subject: perf/core: Bail out early if the request AUX area is out of bound + +From: Shuai Xue + +[ Upstream commit 54aee5f15b83437f23b2b2469bcf21bdd9823916 ] + +When perf-record with a large AUX area, e.g 4GB, it fails with: + + #perf record -C 0 -m ,4G -e arm_spe_0// -- sleep 1 + failed to mmap with 12 (Cannot allocate memory) + +and it reveals a WARNING with __alloc_pages(): + + ------------[ cut here ]------------ + WARNING: CPU: 44 PID: 17573 at mm/page_alloc.c:5568 __alloc_pages+0x1ec/0x248 + Call trace: + __alloc_pages+0x1ec/0x248 + __kmalloc_large_node+0xc0/0x1f8 + __kmalloc_node+0x134/0x1e8 + rb_alloc_aux+0xe0/0x298 + perf_mmap+0x440/0x660 + mmap_region+0x308/0x8a8 + do_mmap+0x3c0/0x528 + vm_mmap_pgoff+0xf4/0x1b8 + ksys_mmap_pgoff+0x18c/0x218 + __arm64_sys_mmap+0x38/0x58 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0x58/0x188 + do_el0_svc+0x34/0x50 + el0_svc+0x34/0x108 + el0t_64_sync_handler+0xb8/0xc0 + el0t_64_sync+0x1a4/0x1a8 + +'rb->aux_pages' allocated by kcalloc() is a pointer array which is used to +maintains AUX trace pages. The allocated page for this array is physically +contiguous (and virtually contiguous) with an order of 0..MAX_ORDER. If the +size of pointer array crosses the limitation set by MAX_ORDER, it reveals a +WARNING. + +So bail out early with -ENOMEM if the request AUX area is out of bound, +e.g.: + + #perf record -C 0 -m ,4G -e arm_spe_0// -- sleep 1 + failed to mmap with 12 (Cannot allocate memory) + +Signed-off-by: Shuai Xue +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Signed-off-by: Sasha Levin +--- + kernel/events/ring_buffer.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index a0433f37b0243..4a260ceed9c73 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -699,6 +699,12 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event, + watermark = 0; + } + ++ /* ++ * kcalloc_node() is unable to allocate buffer if the size is larger ++ * than: PAGE_SIZE << MAX_ORDER; directly bail out in this case. ++ */ ++ if (get_order((unsigned long)nr_pages * sizeof(void *)) > MAX_ORDER) ++ return -ENOMEM; + rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL, + node); + if (!rb->aux_pages) +-- +2.42.0 + diff --git a/queue-6.5/phy-qualcomm-phy-qcom-eusb2-repeater-use-regmap_fiel.patch b/queue-6.5/phy-qualcomm-phy-qcom-eusb2-repeater-use-regmap_fiel.patch new file mode 100644 index 00000000000..1b2fd1bdc13 --- /dev/null +++ b/queue-6.5/phy-qualcomm-phy-qcom-eusb2-repeater-use-regmap_fiel.patch @@ -0,0 +1,200 @@ +From 5dea839774cbdef28dc0995ef015222693a15293 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 11:53:24 +0200 +Subject: phy: qualcomm: phy-qcom-eusb2-repeater: Use regmap_fields + +From: Konrad Dybcio + +[ Upstream commit 4ba2e52718c0ce4ece6a269bec84319c355c030f ] + +Switch to regmap_fields, so that the values written into registers are +sanitized by their explicit sizes and the different registers are +structured in an iterable object to make external changes to the init +sequence simpler. + +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230830-topic-eusb2_override-v2-2-7d8c893d93f6@linaro.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + .../phy/qualcomm/phy-qcom-eusb2-repeater.c | 91 +++++++++++++------ + 1 file changed, 61 insertions(+), 30 deletions(-) + +diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +index 90f8543ba265b..b20b805414a2a 100644 +--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c ++++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +@@ -29,14 +29,42 @@ + #define EUSB2_TUNE_SQUELCH_U 0x54 + #define EUSB2_TUNE_USB2_PREEM 0x57 + +-#define QCOM_EUSB2_REPEATER_INIT_CFG(o, v) \ ++#define QCOM_EUSB2_REPEATER_INIT_CFG(r, v) \ + { \ +- .offset = o, \ ++ .reg = r, \ + .val = v, \ + } + ++enum reg_fields { ++ F_TUNE_USB2_PREEM, ++ F_TUNE_SQUELCH_U, ++ F_TUNE_IUSB2, ++ F_NUM_TUNE_FIELDS, ++ ++ F_FORCE_VAL_5 = F_NUM_TUNE_FIELDS, ++ F_FORCE_EN_5, ++ ++ F_EN_CTL1, ++ ++ F_RPTR_STATUS, ++ F_NUM_FIELDS, ++}; ++ ++static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = { ++ [F_TUNE_USB2_PREEM] = REG_FIELD(EUSB2_TUNE_USB2_PREEM, 0, 2), ++ [F_TUNE_SQUELCH_U] = REG_FIELD(EUSB2_TUNE_SQUELCH_U, 0, 2), ++ [F_TUNE_IUSB2] = REG_FIELD(EUSB2_TUNE_IUSB2, 0, 3), ++ ++ [F_FORCE_VAL_5] = REG_FIELD(EUSB2_FORCE_VAL_5, 0, 7), ++ [F_FORCE_EN_5] = REG_FIELD(EUSB2_FORCE_EN_5, 0, 7), ++ ++ [F_EN_CTL1] = REG_FIELD(EUSB2_EN_CTL1, 0, 7), ++ ++ [F_RPTR_STATUS] = REG_FIELD(EUSB2_RPTR_STATUS, 0, 7), ++}; ++ + struct eusb2_repeater_init_tbl { +- unsigned int offset; ++ unsigned int reg; + unsigned int val; + }; + +@@ -49,11 +77,10 @@ struct eusb2_repeater_cfg { + + struct eusb2_repeater { + struct device *dev; +- struct regmap *regmap; ++ struct regmap_field *regs[F_NUM_FIELDS]; + struct phy *phy; + struct regulator_bulk_data *vregs; + const struct eusb2_repeater_cfg *cfg; +- u16 base; + enum phy_mode mode; + }; + +@@ -62,9 +89,9 @@ static const char * const pm8550b_vreg_l[] = { + }; + + static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = { +- QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_IUSB2, 0x8), +- QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_SQUELCH_U, 0x3), +- QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_USB2_PREEM, 0x5), ++ QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_IUSB2, 0x8), ++ QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_SQUELCH_U, 0x3), ++ QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_USB2_PREEM, 0x5), + }; + + static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { +@@ -94,7 +121,6 @@ static int eusb2_repeater_init(struct phy *phy) + { + struct eusb2_repeater *rptr = phy_get_drvdata(phy); + const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl; +- int num = rptr->cfg->init_tbl_num; + u32 val; + int ret; + int i; +@@ -103,17 +129,14 @@ static int eusb2_repeater_init(struct phy *phy) + if (ret) + return ret; + +- regmap_update_bits(rptr->regmap, rptr->base + EUSB2_EN_CTL1, +- EUSB2_RPTR_EN, EUSB2_RPTR_EN); ++ regmap_field_update_bits(rptr->regs[F_EN_CTL1], EUSB2_RPTR_EN, EUSB2_RPTR_EN); + +- for (i = 0; i < num; i++) +- regmap_update_bits(rptr->regmap, +- rptr->base + init_tbl[i].offset, +- init_tbl[i].val, init_tbl[i].val); ++ for (i = 0; i < rptr->cfg->init_tbl_num; i++) ++ regmap_field_update_bits(rptr->regs[init_tbl[i].reg], ++ init_tbl[i].val, init_tbl[i].val); + +- ret = regmap_read_poll_timeout(rptr->regmap, +- rptr->base + EUSB2_RPTR_STATUS, val, +- val & RPTR_OK, 10, 5); ++ ret = regmap_field_read_poll_timeout(rptr->regs[F_RPTR_STATUS], ++ val, val & RPTR_OK, 10, 5); + if (ret) + dev_err(rptr->dev, "initialization timed-out\n"); + +@@ -132,10 +155,10 @@ static int eusb2_repeater_set_mode(struct phy *phy, + * per eUSB 1.2 Spec. Below implement software workaround until + * PHY and controller is fixing seen observation. + */ +- regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5, +- F_CLK_19P2M_EN, F_CLK_19P2M_EN); +- regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5, +- V_CLK_19P2M_EN, V_CLK_19P2M_EN); ++ regmap_field_update_bits(rptr->regs[F_FORCE_EN_5], ++ F_CLK_19P2M_EN, F_CLK_19P2M_EN); ++ regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5], ++ V_CLK_19P2M_EN, V_CLK_19P2M_EN); + break; + case PHY_MODE_USB_DEVICE: + /* +@@ -144,10 +167,10 @@ static int eusb2_repeater_set_mode(struct phy *phy, + * repeater doesn't clear previous value due to shared + * regulators (say host <-> device mode switch). + */ +- regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5, +- F_CLK_19P2M_EN, 0); +- regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5, +- V_CLK_19P2M_EN, 0); ++ regmap_field_update_bits(rptr->regs[F_FORCE_EN_5], ++ F_CLK_19P2M_EN, 0); ++ regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5], ++ V_CLK_19P2M_EN, 0); + break; + default: + return -EINVAL; +@@ -176,8 +199,9 @@ static int eusb2_repeater_probe(struct platform_device *pdev) + struct device *dev = &pdev->dev; + struct phy_provider *phy_provider; + struct device_node *np = dev->of_node; ++ struct regmap *regmap; ++ int i, ret; + u32 res; +- int ret; + + rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL); + if (!rptr) +@@ -190,15 +214,22 @@ static int eusb2_repeater_probe(struct platform_device *pdev) + if (!rptr->cfg) + return -EINVAL; + +- rptr->regmap = dev_get_regmap(dev->parent, NULL); +- if (!rptr->regmap) ++ regmap = dev_get_regmap(dev->parent, NULL); ++ if (!regmap) + return -ENODEV; + + ret = of_property_read_u32(np, "reg", &res); + if (ret < 0) + return ret; + +- rptr->base = res; ++ for (i = 0; i < F_NUM_FIELDS; i++) ++ eusb2_repeater_tune_reg_fields[i].reg += res; ++ ++ ret = devm_regmap_field_bulk_alloc(dev, regmap, rptr->regs, ++ eusb2_repeater_tune_reg_fields, ++ F_NUM_FIELDS); ++ if (ret) ++ return ret; + + ret = eusb2_repeater_init_vregs(rptr); + if (ret < 0) { +-- +2.42.0 + diff --git a/queue-6.5/phy-qualcomm-phy-qcom-eusb2-repeater-zero-out-untouc.patch b/queue-6.5/phy-qualcomm-phy-qcom-eusb2-repeater-zero-out-untouc.patch new file mode 100644 index 00000000000..f1f0c3db07c --- /dev/null +++ b/queue-6.5/phy-qualcomm-phy-qcom-eusb2-repeater-zero-out-untouc.patch @@ -0,0 +1,146 @@ +From cf5a7e8bd4061902325f41e7ccbabd653f030634 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 11:53:25 +0200 +Subject: phy: qualcomm: phy-qcom-eusb2-repeater: Zero out untouched tuning + regs + +From: Konrad Dybcio + +[ Upstream commit 99a517a582fc1272d1d3cf3b9e671a14d7db77b8 ] + +The vendor kernel zeroes out all tuning data outside the init sequence +as part of initialization. Follow suit to avoid UB. + +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20230830-topic-eusb2_override-v2-3-7d8c893d93f6@linaro.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + .../phy/qualcomm/phy-qcom-eusb2-repeater.c | 58 ++++++++++++++----- + 1 file changed, 44 insertions(+), 14 deletions(-) + +diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +index b20b805414a2a..6777532dd4dc9 100644 +--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c ++++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +@@ -25,9 +25,18 @@ + #define EUSB2_FORCE_VAL_5 0xeD + #define V_CLK_19P2M_EN BIT(6) + ++#define EUSB2_TUNE_USB2_CROSSOVER 0x50 + #define EUSB2_TUNE_IUSB2 0x51 ++#define EUSB2_TUNE_RES_FSDIF 0x52 ++#define EUSB2_TUNE_HSDISC 0x53 + #define EUSB2_TUNE_SQUELCH_U 0x54 ++#define EUSB2_TUNE_USB2_SLEW 0x55 ++#define EUSB2_TUNE_USB2_EQU 0x56 + #define EUSB2_TUNE_USB2_PREEM 0x57 ++#define EUSB2_TUNE_USB2_HS_COMP_CUR 0x58 ++#define EUSB2_TUNE_EUSB_SLEW 0x59 ++#define EUSB2_TUNE_EUSB_EQU 0x5A ++#define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B + + #define QCOM_EUSB2_REPEATER_INIT_CFG(r, v) \ + { \ +@@ -36,9 +45,18 @@ + } + + enum reg_fields { ++ F_TUNE_EUSB_HS_COMP_CUR, ++ F_TUNE_EUSB_EQU, ++ F_TUNE_EUSB_SLEW, ++ F_TUNE_USB2_HS_COMP_CUR, + F_TUNE_USB2_PREEM, ++ F_TUNE_USB2_EQU, ++ F_TUNE_USB2_SLEW, + F_TUNE_SQUELCH_U, ++ F_TUNE_HSDISC, ++ F_TUNE_RES_FSDIF, + F_TUNE_IUSB2, ++ F_TUNE_USB2_CROSSOVER, + F_NUM_TUNE_FIELDS, + + F_FORCE_VAL_5 = F_NUM_TUNE_FIELDS, +@@ -51,9 +69,18 @@ enum reg_fields { + }; + + static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = { ++ [F_TUNE_EUSB_HS_COMP_CUR] = REG_FIELD(EUSB2_TUNE_EUSB_HS_COMP_CUR, 0, 1), ++ [F_TUNE_EUSB_EQU] = REG_FIELD(EUSB2_TUNE_EUSB_EQU, 0, 1), ++ [F_TUNE_EUSB_SLEW] = REG_FIELD(EUSB2_TUNE_EUSB_SLEW, 0, 1), ++ [F_TUNE_USB2_HS_COMP_CUR] = REG_FIELD(EUSB2_TUNE_USB2_HS_COMP_CUR, 0, 1), + [F_TUNE_USB2_PREEM] = REG_FIELD(EUSB2_TUNE_USB2_PREEM, 0, 2), ++ [F_TUNE_USB2_EQU] = REG_FIELD(EUSB2_TUNE_USB2_EQU, 0, 1), ++ [F_TUNE_USB2_SLEW] = REG_FIELD(EUSB2_TUNE_USB2_SLEW, 0, 1), + [F_TUNE_SQUELCH_U] = REG_FIELD(EUSB2_TUNE_SQUELCH_U, 0, 2), ++ [F_TUNE_HSDISC] = REG_FIELD(EUSB2_TUNE_HSDISC, 0, 2), ++ [F_TUNE_RES_FSDIF] = REG_FIELD(EUSB2_TUNE_RES_FSDIF, 0, 2), + [F_TUNE_IUSB2] = REG_FIELD(EUSB2_TUNE_IUSB2, 0, 3), ++ [F_TUNE_USB2_CROSSOVER] = REG_FIELD(EUSB2_TUNE_USB2_CROSSOVER, 0, 2), + + [F_FORCE_VAL_5] = REG_FIELD(EUSB2_FORCE_VAL_5, 0, 7), + [F_FORCE_EN_5] = REG_FIELD(EUSB2_FORCE_EN_5, 0, 7), +@@ -63,13 +90,8 @@ static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = { + [F_RPTR_STATUS] = REG_FIELD(EUSB2_RPTR_STATUS, 0, 7), + }; + +-struct eusb2_repeater_init_tbl { +- unsigned int reg; +- unsigned int val; +-}; +- + struct eusb2_repeater_cfg { +- const struct eusb2_repeater_init_tbl *init_tbl; ++ const u32 *init_tbl; + int init_tbl_num; + const char * const *vreg_list; + int num_vregs; +@@ -88,10 +110,10 @@ static const char * const pm8550b_vreg_l[] = { + "vdd18", "vdd3", + }; + +-static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = { +- QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_IUSB2, 0x8), +- QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_SQUELCH_U, 0x3), +- QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_USB2_PREEM, 0x5), ++static const u32 pm8550b_init_tbl[F_NUM_TUNE_FIELDS] = { ++ [F_TUNE_IUSB2] = 0x8, ++ [F_TUNE_SQUELCH_U] = 0x3, ++ [F_TUNE_USB2_PREEM] = 0x5, + }; + + static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { +@@ -119,8 +141,9 @@ static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr) + + static int eusb2_repeater_init(struct phy *phy) + { ++ struct reg_field *regfields = eusb2_repeater_tune_reg_fields; + struct eusb2_repeater *rptr = phy_get_drvdata(phy); +- const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl; ++ const u32 *init_tbl = rptr->cfg->init_tbl; + u32 val; + int ret; + int i; +@@ -131,9 +154,16 @@ static int eusb2_repeater_init(struct phy *phy) + + regmap_field_update_bits(rptr->regs[F_EN_CTL1], EUSB2_RPTR_EN, EUSB2_RPTR_EN); + +- for (i = 0; i < rptr->cfg->init_tbl_num; i++) +- regmap_field_update_bits(rptr->regs[init_tbl[i].reg], +- init_tbl[i].val, init_tbl[i].val); ++ for (i = 0; i < F_NUM_TUNE_FIELDS; i++) { ++ if (init_tbl[i]) { ++ regmap_field_update_bits(rptr->regs[i], init_tbl[i], init_tbl[i]); ++ } else { ++ /* Write 0 if there's no value set */ ++ u32 mask = GENMASK(regfields[i].msb, regfields[i].lsb); ++ ++ regmap_field_update_bits(rptr->regs[i], mask, 0); ++ } ++ } + + ret = regmap_field_read_poll_timeout(rptr->regs[F_RPTR_STATUS], + val, val & RPTR_OK, 10, 5); +-- +2.42.0 + diff --git a/queue-6.5/platform-chrome-kunit-initialize-lock-for-fake-ec_de.patch b/queue-6.5/platform-chrome-kunit-initialize-lock-for-fake-ec_de.patch new file mode 100644 index 00000000000..4a806c17d90 --- /dev/null +++ b/queue-6.5/platform-chrome-kunit-initialize-lock-for-fake-ec_de.patch @@ -0,0 +1,44 @@ +From 54dd6374ad04d85492bf08d2ca42cd85e3b077b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Oct 2023 08:05:04 +0000 +Subject: platform/chrome: kunit: initialize lock for fake ec_dev + +From: Tzung-Bi Shih + +[ Upstream commit e410b4ade83d06a046f6e32b5085997502ba0559 ] + +cros_ec_cmd_xfer() uses ec_dev->lock. Initialize it. + +Otherwise, dmesg shows the following: +> DEBUG_LOCKS_WARN_ON(lock->magic != lock) +> ... +> Call Trace: +> ? __mutex_lock +> ? __warn +> ? __mutex_lock +> ... +> ? cros_ec_cmd_xfer + +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20231003080504.4011337-1-tzungbi@kernel.org +Signed-off-by: Tzung-Bi Shih +Signed-off-by: Sasha Levin +--- + drivers/platform/chrome/cros_ec_proto_test.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/chrome/cros_ec_proto_test.c b/drivers/platform/chrome/cros_ec_proto_test.c +index 5b9748e0463bc..63e38671e95a6 100644 +--- a/drivers/platform/chrome/cros_ec_proto_test.c ++++ b/drivers/platform/chrome/cros_ec_proto_test.c +@@ -2668,6 +2668,7 @@ static int cros_ec_proto_test_init(struct kunit *test) + ec_dev->dev->release = cros_ec_proto_test_release; + ec_dev->cmd_xfer = cros_kunit_ec_xfer_mock; + ec_dev->pkt_xfer = cros_kunit_ec_xfer_mock; ++ mutex_init(&ec_dev->lock); + + priv->msg = (struct cros_ec_command *)priv->_msg; + +-- +2.42.0 + diff --git a/queue-6.5/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch b/queue-6.5/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch new file mode 100644 index 00000000000..d3b59b098d4 --- /dev/null +++ b/queue-6.5/platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch @@ -0,0 +1,38 @@ +From 5cb6f998ba2c04044ca765f9f98574b5e9ae48e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 22:09:21 +0300 +Subject: platform/x86: thinkpad_acpi: Add battery quirk for Thinkpad X120e +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Olli Asikainen + +[ Upstream commit 916646758aea81a143ce89103910f715ed923346 ] + +Thinkpad X120e also needs this battery quirk. + +Signed-off-by: Olli Asikainen +Link: https://lore.kernel.org/r/20231024190922.2742-1-olli.asikainen@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/thinkpad_acpi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index ad460417f901a..4b13d3e704bf3 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -9810,6 +9810,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = { + * Individual addressing is broken on models that expose the + * primary battery as BAT1. + */ ++ TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */ + TPACPI_Q_LNV('J', '7', true), /* B5400 */ + TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */ + TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */ +-- +2.42.0 + diff --git a/queue-6.5/ppp-limit-mru-to-64k.patch b/queue-6.5/ppp-limit-mru-to-64k.patch new file mode 100644 index 00000000000..5f6aeb058f7 --- /dev/null +++ b/queue-6.5/ppp-limit-mru-to-64k.patch @@ -0,0 +1,76 @@ +From 4aa23ec70153fd13716d76f0c2d042a644a6bd2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Nov 2023 22:16:32 -0500 +Subject: ppp: limit MRU to 64K + +From: Willem de Bruijn + +[ Upstream commit c0a2a1b0d631fc460d830f52d06211838874d655 ] + +ppp_sync_ioctl allows setting device MRU, but does not sanity check +this input. + +Limit to a sane upper bound of 64KB. + +No implementation I could find generates larger than 64KB frames. +RFC 2823 mentions an upper bound of PPP over SDL of 64KB based on the +16-bit length field. Other protocols will be smaller, such as PPPoE +(9KB jumbo frame) and PPPoA (18190 maximum CPCS-SDU size, RFC 2364). +PPTP and L2TP encapsulate in IP. + +Syzbot managed to trigger alloc warning in __alloc_pages: + + if (WARN_ON_ONCE_GFP(order > MAX_ORDER, gfp)) + + WARNING: CPU: 1 PID: 37 at mm/page_alloc.c:4544 __alloc_pages+0x3ab/0x4a0 mm/page_alloc.c:4544 + + __alloc_skb+0x12b/0x330 net/core/skbuff.c:651 + __netdev_alloc_skb+0x72/0x3f0 net/core/skbuff.c:715 + netdev_alloc_skb include/linux/skbuff.h:3225 [inline] + dev_alloc_skb include/linux/skbuff.h:3238 [inline] + ppp_sync_input drivers/net/ppp/ppp_synctty.c:669 [inline] + ppp_sync_receive+0xff/0x680 drivers/net/ppp/ppp_synctty.c:334 + tty_ldisc_receive_buf+0x14c/0x180 drivers/tty/tty_buffer.c:390 + tty_port_default_receive_buf+0x70/0xb0 drivers/tty/tty_port.c:37 + receive_buf drivers/tty/tty_buffer.c:444 [inline] + flush_to_ldisc+0x261/0x780 drivers/tty/tty_buffer.c:494 + process_one_work+0x884/0x15c0 kernel/workqueue.c:2630 + +With call + + ioctl$PPPIOCSMRU1(r1, 0x40047452, &(0x7f0000000100)=0x5e6417a8) + +Similar code exists in other drivers that implement ppp_channel_ops +ioctl PPPIOCSMRU. Those might also be in scope. Notably excluded from +this are pppol2tp_ioctl and pppoe_ioctl. + +This code goes back to the start of git history. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+6177e1f90d92583bcc58@syzkaller.appspotmail.com +Signed-off-by: Willem de Bruijn +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ppp/ppp_synctty.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c +index 1ac231408398a..94ef6f9ca5103 100644 +--- a/drivers/net/ppp/ppp_synctty.c ++++ b/drivers/net/ppp/ppp_synctty.c +@@ -462,6 +462,10 @@ ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) + case PPPIOCSMRU: + if (get_user(val, (int __user *) argp)) + break; ++ if (val > U16_MAX) { ++ err = -EINVAL; ++ break; ++ } + if (val < PPP_MRU) + val = PPP_MRU; + ap->mru = val; +-- +2.42.0 + diff --git a/queue-6.5/ptp-annotate-data-race-around-q-head-and-q-tail.patch b/queue-6.5/ptp-annotate-data-race-around-q-head-and-q-tail.patch new file mode 100644 index 00000000000..1a764e3b9a9 --- /dev/null +++ b/queue-6.5/ptp-annotate-data-race-around-q-head-and-q-tail.patch @@ -0,0 +1,98 @@ +From ebc880ce1189649132b5f581e396884d5f6d87d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 17:48:59 +0000 +Subject: ptp: annotate data-race around q->head and q->tail + +From: Eric Dumazet + +[ Upstream commit 73bde5a3294853947252cd9092a3517c7cb0cd2d ] + +As I was working on a syzbot report, I found that KCSAN would +probably complain that reading q->head or q->tail without +barriers could lead to invalid results. + +Add corresponding READ_ONCE() and WRITE_ONCE() to avoid +load-store tearing. + +Fixes: d94ba80ebbea ("ptp: Added a brand new class driver for ptp clocks.") +Signed-off-by: Eric Dumazet +Acked-by: Richard Cochran +Link: https://lore.kernel.org/r/20231109174859.3995880-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/ptp/ptp_chardev.c | 3 ++- + drivers/ptp/ptp_clock.c | 5 +++-- + drivers/ptp/ptp_private.h | 8 ++++++-- + drivers/ptp/ptp_sysfs.c | 3 ++- + 4 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 362bf756e6b78..5a3a4cc0bec82 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -490,7 +490,8 @@ ssize_t ptp_read(struct posix_clock *pc, + + for (i = 0; i < cnt; i++) { + event[i] = queue->buf[queue->head]; +- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; ++ /* Paired with READ_ONCE() in queue_cnt() */ ++ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); + } + + spin_unlock_irqrestore(&queue->lock, flags); +diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c +index 80f74e38c2da4..9a50bfb56453c 100644 +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -56,10 +56,11 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue, + dst->t.sec = seconds; + dst->t.nsec = remainder; + ++ /* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */ + if (!queue_free(queue)) +- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; ++ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); + +- queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS; ++ WRITE_ONCE(queue->tail, (queue->tail + 1) % PTP_MAX_TIMESTAMPS); + + spin_unlock_irqrestore(&queue->lock, flags); + } +diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h +index 75f58fc468a71..b8d4f61f14be4 100644 +--- a/drivers/ptp/ptp_private.h ++++ b/drivers/ptp/ptp_private.h +@@ -76,9 +76,13 @@ struct ptp_vclock { + * that a writer might concurrently increment the tail does not + * matter, since the queue remains nonempty nonetheless. + */ +-static inline int queue_cnt(struct timestamp_event_queue *q) ++static inline int queue_cnt(const struct timestamp_event_queue *q) + { +- int cnt = q->tail - q->head; ++ /* ++ * Paired with WRITE_ONCE() in enqueue_external_timestamp(), ++ * ptp_read(), extts_fifo_show(). ++ */ ++ int cnt = READ_ONCE(q->tail) - READ_ONCE(q->head); + return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; + } + +diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c +index 6e4d5456a8851..34ea5c16123a1 100644 +--- a/drivers/ptp/ptp_sysfs.c ++++ b/drivers/ptp/ptp_sysfs.c +@@ -90,7 +90,8 @@ static ssize_t extts_fifo_show(struct device *dev, + qcnt = queue_cnt(queue); + if (qcnt) { + event = queue->buf[queue->head]; +- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; ++ /* Paired with READ_ONCE() in queue_cnt() */ ++ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); + } + spin_unlock_irqrestore(&queue->lock, flags); + +-- +2.42.0 + diff --git a/queue-6.5/pwm-fix-double-shift-bug.patch b/queue-6.5/pwm-fix-double-shift-bug.patch new file mode 100644 index 00000000000..947c139f722 --- /dev/null +++ b/queue-6.5/pwm-fix-double-shift-bug.patch @@ -0,0 +1,45 @@ +From 44608d8c5368c26629a61a4f7831e1e67123e444 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Oct 2023 14:58:18 +0300 +Subject: pwm: Fix double shift bug +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dan Carpenter + +[ Upstream commit d27abbfd4888d79dd24baf50e774631046ac4732 ] + +These enums are passed to set/test_bit(). The set/test_bit() functions +take a bit number instead of a shifted value. Passing a shifted value +is a double shift bug like doing BIT(BIT(1)). The double shift bug +doesn't cause a problem here because we are only checking 0 and 1 but +if the value was 5 or above then it can lead to a buffer overflow. + +Signed-off-by: Dan Carpenter +Reviewed-by: Uwe Kleine-König +Reviewed-by: Sam Protsenko +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + include/linux/pwm.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/pwm.h b/include/linux/pwm.h +index 04ae1d9073a74..0755ba9938f74 100644 +--- a/include/linux/pwm.h ++++ b/include/linux/pwm.h +@@ -41,8 +41,8 @@ struct pwm_args { + }; + + enum { +- PWMF_REQUESTED = 1 << 0, +- PWMF_EXPORTED = 1 << 1, ++ PWMF_REQUESTED = 0, ++ PWMF_EXPORTED = 1, + }; + + /* +-- +2.42.0 + diff --git a/queue-6.5/rcu-dump-memory-object-info-if-callback-function-is-.patch b/queue-6.5/rcu-dump-memory-object-info-if-callback-function-is-.patch new file mode 100644 index 00000000000..7a7aede50c1 --- /dev/null +++ b/queue-6.5/rcu-dump-memory-object-info-if-callback-function-is-.patch @@ -0,0 +1,149 @@ +From 0763a36c99e66750a280b61311aa1aa0563d15b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 5 Aug 2023 11:17:26 +0800 +Subject: rcu: Dump memory object info if callback function is invalid + +From: Zhen Lei + +[ Upstream commit 2cbc482d325ee58001472c4359b311958c4efdd1 ] + +When a structure containing an RCU callback rhp is (incorrectly) freed +and reallocated after rhp is passed to call_rcu(), it is not unusual for +rhp->func to be set to NULL. This defeats the debugging prints used by +__call_rcu_common() in kernels built with CONFIG_DEBUG_OBJECTS_RCU_HEAD=y, +which expect to identify the offending code using the identity of this +function. + +And in kernels build without CONFIG_DEBUG_OBJECTS_RCU_HEAD=y, things +are even worse, as can be seen from this splat: + +Unable to handle kernel NULL pointer dereference at virtual address 0 +... ... +PC is at 0x0 +LR is at rcu_do_batch+0x1c0/0x3b8 +... ... + (rcu_do_batch) from (rcu_core+0x1d4/0x284) + (rcu_core) from (__do_softirq+0x24c/0x344) + (__do_softirq) from (__irq_exit_rcu+0x64/0x108) + (__irq_exit_rcu) from (irq_exit+0x8/0x10) + (irq_exit) from (__handle_domain_irq+0x74/0x9c) + (__handle_domain_irq) from (gic_handle_irq+0x8c/0x98) + (gic_handle_irq) from (__irq_svc+0x5c/0x94) + (__irq_svc) from (arch_cpu_idle+0x20/0x3c) + (arch_cpu_idle) from (default_idle_call+0x4c/0x78) + (default_idle_call) from (do_idle+0xf8/0x150) + (do_idle) from (cpu_startup_entry+0x18/0x20) + (cpu_startup_entry) from (0xc01530) + +This commit therefore adds calls to mem_dump_obj(rhp) to output some +information, for example: + + slab kmalloc-256 start ffff410c45019900 pointer offset 0 size 256 + +This provides the rough size of the memory block and the offset of the +rcu_head structure, which as least provides at least a few clues to help +locate the problem. If the problem is reproducible, additional slab +debugging can be enabled, for example, CONFIG_DEBUG_SLAB=y, which can +provide significantly more information. + +Signed-off-by: Zhen Lei +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/rcu/rcu.h | 7 +++++++ + kernel/rcu/srcutiny.c | 1 + + kernel/rcu/srcutree.c | 1 + + kernel/rcu/tasks.h | 1 + + kernel/rcu/tiny.c | 1 + + kernel/rcu/tree.c | 1 + + 6 files changed, 12 insertions(+) + +diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h +index 98c1544cf572b..7ae3496b0b58d 100644 +--- a/kernel/rcu/rcu.h ++++ b/kernel/rcu/rcu.h +@@ -10,6 +10,7 @@ + #ifndef __LINUX_RCU_H + #define __LINUX_RCU_H + ++#include + #include + + /* +@@ -248,6 +249,12 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head) + } + #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ + ++static inline void debug_rcu_head_callback(struct rcu_head *rhp) ++{ ++ if (unlikely(!rhp->func)) ++ kmem_dump_obj(rhp); ++} ++ + extern int rcu_cpu_stall_suppress_at_boot; + + static inline bool rcu_stall_is_suppressed_at_boot(void) +diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c +index 336af24e0fe35..c38e5933a5d69 100644 +--- a/kernel/rcu/srcutiny.c ++++ b/kernel/rcu/srcutiny.c +@@ -138,6 +138,7 @@ void srcu_drive_gp(struct work_struct *wp) + while (lh) { + rhp = lh; + lh = lh->next; ++ debug_rcu_head_callback(rhp); + local_bh_disable(); + rhp->func(rhp); + local_bh_enable(); +diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c +index 253ed509b6abb..c6481032d42be 100644 +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -1735,6 +1735,7 @@ static void srcu_invoke_callbacks(struct work_struct *work) + rhp = rcu_cblist_dequeue(&ready_cbs); + for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) { + debug_rcu_head_unqueue(rhp); ++ debug_rcu_head_callback(rhp); + local_bh_disable(); + rhp->func(rhp); + local_bh_enable(); +diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h +index b770add3f8430..b64d45cdea9c4 100644 +--- a/kernel/rcu/tasks.h ++++ b/kernel/rcu/tasks.h +@@ -493,6 +493,7 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu + raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags); + len = rcl.len; + for (rhp = rcu_cblist_dequeue(&rcl); rhp; rhp = rcu_cblist_dequeue(&rcl)) { ++ debug_rcu_head_callback(rhp); + local_bh_disable(); + rhp->func(rhp); + local_bh_enable(); +diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c +index 42f7589e51e09..fec804b790803 100644 +--- a/kernel/rcu/tiny.c ++++ b/kernel/rcu/tiny.c +@@ -97,6 +97,7 @@ static inline bool rcu_reclaim_tiny(struct rcu_head *head) + + trace_rcu_invoke_callback("", head); + f = head->func; ++ debug_rcu_head_callback(head); + WRITE_ONCE(head->func, (rcu_callback_t)0L); + f(head); + rcu_lock_release(&rcu_callback_map); +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index 1449cb69a0e0e..9b9ebe6205b93 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -2131,6 +2131,7 @@ static void rcu_do_batch(struct rcu_data *rdp) + trace_rcu_invoke_callback(rcu_state.name, rhp); + + f = rhp->func; ++ debug_rcu_head_callback(rhp); + WRITE_ONCE(rhp->func, (rcu_callback_t)0L); + f(rhp); + +-- +2.42.0 + diff --git a/queue-6.5/rdma-hfi1-use-field_get-to-extract-link-width.patch b/queue-6.5/rdma-hfi1-use-field_get-to-extract-link-width.patch new file mode 100644 index 00000000000..4d3be175b6a --- /dev/null +++ b/queue-6.5/rdma-hfi1-use-field_get-to-extract-link-width.patch @@ -0,0 +1,63 @@ +From 3297a2a15b56e98e638b078567947acc4195efec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 15:56:41 +0300 +Subject: RDMA/hfi1: Use FIELD_GET() to extract Link Width +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 8bf7187d978610b9e327a3d92728c8864a575ebd ] + +Use FIELD_GET() to extract PCIe Negotiated Link Width field instead of +custom masking and shifting, and remove extract_width() which only +wraps that FIELD_GET(). + +Signed-off-by: Ilpo Järvinen +Link: https://lore.kernel.org/r/20230919125648.1920-2-ilpo.jarvinen@linux.intel.com +Reviewed-by: Jonathan Cameron +Reviewed-by: Dean Luick +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/pcie.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c +index 08732e1ac9662..c132a9c073bff 100644 +--- a/drivers/infiniband/hw/hfi1/pcie.c ++++ b/drivers/infiniband/hw/hfi1/pcie.c +@@ -3,6 +3,7 @@ + * Copyright(c) 2015 - 2019 Intel Corporation. + */ + ++#include + #include + #include + #include +@@ -210,12 +211,6 @@ static u32 extract_speed(u16 linkstat) + return speed; + } + +-/* return the PCIe link speed from the given link status */ +-static u32 extract_width(u16 linkstat) +-{ +- return (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; +-} +- + /* read the link status and set dd->{lbus_width,lbus_speed,lbus_info} */ + static void update_lbus_info(struct hfi1_devdata *dd) + { +@@ -228,7 +223,7 @@ static void update_lbus_info(struct hfi1_devdata *dd) + return; + } + +- dd->lbus_width = extract_width(linkstat); ++ dd->lbus_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat); + dd->lbus_speed = extract_speed(linkstat); + snprintf(dd->lbus_info, sizeof(dd->lbus_info), + "PCIe,%uMHz,x%u", dd->lbus_speed, dd->lbus_width); +-- +2.42.0 + diff --git a/queue-6.5/risc-v-hwprobe-fix-vdso-sigsegv.patch b/queue-6.5/risc-v-hwprobe-fix-vdso-sigsegv.patch new file mode 100644 index 00000000000..40dbc46c860 --- /dev/null +++ b/queue-6.5/risc-v-hwprobe-fix-vdso-sigsegv.patch @@ -0,0 +1,56 @@ +From 9c4ddafb514d78c1f46d3ea058efd63f59a4223f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 18:51:02 +0200 +Subject: RISC-V: hwprobe: Fix vDSO SIGSEGV + +From: Andrew Jones + +[ Upstream commit e1c05b3bf80f829ced464bdca90f1dfa96e8d251 ] + +A hwprobe pair key is signed, but the hwprobe vDSO function was +only checking that the upper bound was valid. In order to help +avoid this type of problem in the future, and in anticipation of +this check becoming more complicated with sparse keys, introduce +and use a "key is valid" predicate function for the check. + +Fixes: aa5af0aa90ba ("RISC-V: Add hwprobe vDSO function and data") +Signed-off-by: Andrew Jones +Reviewed-by: Evan Green +Link: https://lore.kernel.org/r/20231010165101.14942-2-ajones@ventanamicro.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/hwprobe.h | 5 +++++ + arch/riscv/kernel/vdso/hwprobe.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h +index 78936f4ff5133..7cad513538d8d 100644 +--- a/arch/riscv/include/asm/hwprobe.h ++++ b/arch/riscv/include/asm/hwprobe.h +@@ -10,4 +10,9 @@ + + #define RISCV_HWPROBE_MAX_KEY 5 + ++static inline bool riscv_hwprobe_key_is_valid(__s64 key) ++{ ++ return key >= 0 && key <= RISCV_HWPROBE_MAX_KEY; ++} ++ + #endif +diff --git a/arch/riscv/kernel/vdso/hwprobe.c b/arch/riscv/kernel/vdso/hwprobe.c +index d40bec6ac0786..cadf725ef7983 100644 +--- a/arch/riscv/kernel/vdso/hwprobe.c ++++ b/arch/riscv/kernel/vdso/hwprobe.c +@@ -37,7 +37,7 @@ int __vdso_riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, + + /* This is something we can handle, fill out the pairs. */ + while (p < end) { +- if (p->key <= RISCV_HWPROBE_MAX_KEY) { ++ if (riscv_hwprobe_key_is_valid(p->key)) { + p->value = avd->all_cpu_hwprobe_values[p->key]; + + } else { +-- +2.42.0 + diff --git a/queue-6.5/riscv-provide-riscv-specific-is_trap_insn.patch b/queue-6.5/riscv-provide-riscv-specific-is_trap_insn.patch new file mode 100644 index 00000000000..c120c275ac6 --- /dev/null +++ b/queue-6.5/riscv-provide-riscv-specific-is_trap_insn.patch @@ -0,0 +1,62 @@ +From f054f8d1117644e194054c321f5443402506ea0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 10:36:15 +0200 +Subject: riscv: provide riscv-specific is_trap_insn() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nam Cao + +[ Upstream commit b701f9e726f0a30a94ea6af596b74c1f07b95b6b ] + +uprobes expects is_trap_insn() to return true for any trap instructions, +not just the one used for installing uprobe. The current default +implementation only returns true for 16-bit c.ebreak if C extension is +enabled. This can confuse uprobes if a 32-bit ebreak generates a trap +exception from userspace: uprobes asks is_trap_insn() who says there is no +trap, so uprobes assume a probe was there before but has been removed, and +return to the trap instruction. This causes an infinite loop of entering +and exiting trap handler. + +Instead of using the default implementation, implement this function +speficially for riscv with checks for both ebreak and c.ebreak. + +Fixes: 74784081aac8 ("riscv: Add uprobes supported") +Signed-off-by: Nam Cao +Tested-by: Björn Töpel +Reviewed-by: Guo Ren +Link: https://lore.kernel.org/r/20230829083614.117748-1-namcaov@gmail.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/kernel/probes/uprobes.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c +index 194f166b2cc40..4b3dc8beaf77d 100644 +--- a/arch/riscv/kernel/probes/uprobes.c ++++ b/arch/riscv/kernel/probes/uprobes.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + + #include "decode-insn.h" + +@@ -17,6 +18,11 @@ bool is_swbp_insn(uprobe_opcode_t *insn) + #endif + } + ++bool is_trap_insn(uprobe_opcode_t *insn) ++{ ++ return riscv_insn_is_ebreak(*insn) || riscv_insn_is_c_ebreak(*insn); ++} ++ + unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) + { + return instruction_pointer(regs); +-- +2.42.0 + diff --git a/queue-6.5/riscv-vmap_stack-overflow-detection-thread-safe.patch b/queue-6.5/riscv-vmap_stack-overflow-detection-thread-safe.patch new file mode 100644 index 00000000000..1d6e9c91979 --- /dev/null +++ b/queue-6.5/riscv-vmap_stack-overflow-detection-thread-safe.patch @@ -0,0 +1,308 @@ +From d48a43a4b56b9225905550d46d067e44d9b4adab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 22:47:59 +0000 +Subject: riscv: VMAP_STACK overflow detection thread-safe + +From: Deepak Gupta + +[ Upstream commit be97d0db5f44c0674480cb79ac6f5b0529b84c76 ] + +commit 31da94c25aea ("riscv: add VMAP_STACK overflow detection") added +support for CONFIG_VMAP_STACK. If overflow is detected, CPU switches to +`shadow_stack` temporarily before switching finally to per-cpu +`overflow_stack`. + +If two CPUs/harts are racing and end up in over flowing kernel stack, one +or both will end up corrupting each other state because `shadow_stack` is +not per-cpu. This patch optimizes per-cpu overflow stack switch by +directly picking per-cpu `overflow_stack` and gets rid of `shadow_stack`. + +Following are the changes in this patch + + - Defines an asm macro to obtain per-cpu symbols in destination + register. + - In entry.S, when overflow is detected, per-cpu overflow stack is + located using per-cpu asm macro. Computing per-cpu symbol requires + a temporary register. x31 is saved away into CSR_SCRATCH + (CSR_SCRATCH is anyways zero since we're in kernel). + +Please see Links for additional relevant disccussion and alternative +solution. + +Tested by `echo EXHAUST_STACK > /sys/kernel/debug/provoke-crash/DIRECT` +Kernel crash log below + + Insufficient stack space to handle exception!/debug/provoke-crash/DIRECT + Task stack: [0xff20000010a98000..0xff20000010a9c000] + Overflow stack: [0xff600001f7d98370..0xff600001f7d99370] + CPU: 1 PID: 205 Comm: bash Not tainted 6.1.0-rc2-00001-g328a1f96f7b9 #34 + Hardware name: riscv-virtio,qemu (DT) + epc : __memset+0x60/0xfc + ra : recursive_loop+0x48/0xc6 [lkdtm] + epc : ffffffff808de0e4 ra : ffffffff0163a752 sp : ff20000010a97e80 + gp : ffffffff815c0330 tp : ff600000820ea280 t0 : ff20000010a97e88 + t1 : 000000000000002e t2 : 3233206874706564 s0 : ff20000010a982b0 + s1 : 0000000000000012 a0 : ff20000010a97e88 a1 : 0000000000000000 + a2 : 0000000000000400 a3 : ff20000010a98288 a4 : 0000000000000000 + a5 : 0000000000000000 a6 : fffffffffffe43f0 a7 : 00007fffffffffff + s2 : ff20000010a97e88 s3 : ffffffff01644680 s4 : ff20000010a9be90 + s5 : ff600000842ba6c0 s6 : 00aaaaaac29e42b0 s7 : 00fffffff0aa3684 + s8 : 00aaaaaac2978040 s9 : 0000000000000065 s10: 00ffffff8a7cad10 + s11: 00ffffff8a76a4e0 t3 : ffffffff815dbaf4 t4 : ffffffff815dbaf4 + t5 : ffffffff815dbab8 t6 : ff20000010a9bb48 + status: 0000000200000120 badaddr: ff20000010a97e88 cause: 000000000000000f + Kernel panic - not syncing: Kernel stack overflow + CPU: 1 PID: 205 Comm: bash Not tainted 6.1.0-rc2-00001-g328a1f96f7b9 #34 + Hardware name: riscv-virtio,qemu (DT) + Call Trace: + [] dump_backtrace+0x30/0x38 + [] show_stack+0x40/0x4c + [] dump_stack_lvl+0x44/0x5c + [] dump_stack+0x18/0x20 + [] panic+0x126/0x2fe + [] walk_stackframe+0x0/0xf0 + [] recursive_loop+0x48/0xc6 [lkdtm] + SMP: stopping secondary CPUs + ---[ end Kernel panic - not syncing: Kernel stack overflow ]--- + +Cc: Guo Ren +Cc: Jisheng Zhang +Link: https://lore.kernel.org/linux-riscv/Y347B0x4VUNOd6V7@xhacker/T/#t +Link: https://lore.kernel.org/lkml/20221124094845.1907443-1-debug@rivosinc.com/ +Signed-off-by: Deepak Gupta +Co-developed-by: Sami Tolvanen +Signed-off-by: Sami Tolvanen +Acked-by: Guo Ren +Tested-by: Nathan Chancellor +Link: https://lore.kernel.org/r/20230927224757.1154247-9-samitolvanen@google.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/asm-prototypes.h | 1 - + arch/riscv/include/asm/asm.h | 22 ++++++++ + arch/riscv/include/asm/thread_info.h | 3 -- + arch/riscv/kernel/asm-offsets.c | 1 + + arch/riscv/kernel/entry.S | 70 ++++--------------------- + arch/riscv/kernel/traps.c | 36 +------------ + 6 files changed, 34 insertions(+), 99 deletions(-) + +diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h +index 61ba8ed43d8fe..36b955c762ba0 100644 +--- a/arch/riscv/include/asm/asm-prototypes.h ++++ b/arch/riscv/include/asm/asm-prototypes.h +@@ -25,7 +25,6 @@ DECLARE_DO_ERROR_INFO(do_trap_ecall_s); + DECLARE_DO_ERROR_INFO(do_trap_ecall_m); + DECLARE_DO_ERROR_INFO(do_trap_break); + +-asmlinkage unsigned long get_overflow_stack(void); + asmlinkage void handle_bad_stack(struct pt_regs *regs); + asmlinkage void do_page_fault(struct pt_regs *regs); + asmlinkage void do_irq(struct pt_regs *regs); +diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h +index 114bbadaef41e..bfb4c26f113c4 100644 +--- a/arch/riscv/include/asm/asm.h ++++ b/arch/riscv/include/asm/asm.h +@@ -82,6 +82,28 @@ + .endr + .endm + ++#ifdef CONFIG_SMP ++#ifdef CONFIG_32BIT ++#define PER_CPU_OFFSET_SHIFT 2 ++#else ++#define PER_CPU_OFFSET_SHIFT 3 ++#endif ++ ++.macro asm_per_cpu dst sym tmp ++ REG_L \tmp, TASK_TI_CPU_NUM(tp) ++ slli \tmp, \tmp, PER_CPU_OFFSET_SHIFT ++ la \dst, __per_cpu_offset ++ add \dst, \dst, \tmp ++ REG_L \tmp, 0(\dst) ++ la \dst, \sym ++ add \dst, \dst, \tmp ++.endm ++#else /* CONFIG_SMP */ ++.macro asm_per_cpu dst sym tmp ++ la \dst, \sym ++.endm ++#endif /* CONFIG_SMP */ ++ + /* save all GPs except x1 ~ x5 */ + .macro save_from_x6_to_x31 + REG_S x6, PT_T1(sp) +diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h +index 1833beb00489c..d18ce0113ca1f 100644 +--- a/arch/riscv/include/asm/thread_info.h ++++ b/arch/riscv/include/asm/thread_info.h +@@ -34,9 +34,6 @@ + + #ifndef __ASSEMBLY__ + +-extern long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE / sizeof(long)]; +-extern unsigned long spin_shadow_stack; +- + #include + #include + +diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c +index d6a75aac1d27a..9f535d5de33f9 100644 +--- a/arch/riscv/kernel/asm-offsets.c ++++ b/arch/riscv/kernel/asm-offsets.c +@@ -39,6 +39,7 @@ void asm_offsets(void) + OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp); + OFFSET(TASK_TI_USER_SP, task_struct, thread_info.user_sp); + ++ OFFSET(TASK_TI_CPU_NUM, task_struct, thread_info.cpu); + OFFSET(TASK_THREAD_F0, task_struct, thread.fstate.f[0]); + OFFSET(TASK_THREAD_F1, task_struct, thread.fstate.f[1]); + OFFSET(TASK_THREAD_F2, task_struct, thread.fstate.f[2]); +diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S +index 143a2bb3e6976..3d11aa3af105e 100644 +--- a/arch/riscv/kernel/entry.S ++++ b/arch/riscv/kernel/entry.S +@@ -10,9 +10,11 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + + SYM_CODE_START(handle_exception) + /* +@@ -170,67 +172,15 @@ SYM_CODE_END(ret_from_exception) + + #ifdef CONFIG_VMAP_STACK + SYM_CODE_START_LOCAL(handle_kernel_stack_overflow) +- /* +- * Takes the psuedo-spinlock for the shadow stack, in case multiple +- * harts are concurrently overflowing their kernel stacks. We could +- * store any value here, but since we're overflowing the kernel stack +- * already we only have SP to use as a scratch register. So we just +- * swap in the address of the spinlock, as that's definately non-zero. +- * +- * Pairs with a store_release in handle_bad_stack(). +- */ +-1: la sp, spin_shadow_stack +- REG_AMOSWAP_AQ sp, sp, (sp) +- bnez sp, 1b +- +- la sp, shadow_stack +- addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE +- +- //save caller register to shadow stack +- addi sp, sp, -(PT_SIZE_ON_STACK) +- REG_S x1, PT_RA(sp) +- REG_S x5, PT_T0(sp) +- REG_S x6, PT_T1(sp) +- REG_S x7, PT_T2(sp) +- REG_S x10, PT_A0(sp) +- REG_S x11, PT_A1(sp) +- REG_S x12, PT_A2(sp) +- REG_S x13, PT_A3(sp) +- REG_S x14, PT_A4(sp) +- REG_S x15, PT_A5(sp) +- REG_S x16, PT_A6(sp) +- REG_S x17, PT_A7(sp) +- REG_S x28, PT_T3(sp) +- REG_S x29, PT_T4(sp) +- REG_S x30, PT_T5(sp) +- REG_S x31, PT_T6(sp) +- +- la ra, restore_caller_reg +- tail get_overflow_stack +- +-restore_caller_reg: +- //save per-cpu overflow stack +- REG_S a0, -8(sp) +- //restore caller register from shadow_stack +- REG_L x1, PT_RA(sp) +- REG_L x5, PT_T0(sp) +- REG_L x6, PT_T1(sp) +- REG_L x7, PT_T2(sp) +- REG_L x10, PT_A0(sp) +- REG_L x11, PT_A1(sp) +- REG_L x12, PT_A2(sp) +- REG_L x13, PT_A3(sp) +- REG_L x14, PT_A4(sp) +- REG_L x15, PT_A5(sp) +- REG_L x16, PT_A6(sp) +- REG_L x17, PT_A7(sp) +- REG_L x28, PT_T3(sp) +- REG_L x29, PT_T4(sp) +- REG_L x30, PT_T5(sp) +- REG_L x31, PT_T6(sp) ++ /* we reach here from kernel context, sscratch must be 0 */ ++ csrrw x31, CSR_SCRATCH, x31 ++ asm_per_cpu sp, overflow_stack, x31 ++ li x31, OVERFLOW_STACK_SIZE ++ add sp, sp, x31 ++ /* zero out x31 again and restore x31 */ ++ xor x31, x31, x31 ++ csrrw x31, CSR_SCRATCH, x31 + +- //load per-cpu overflow stack +- REG_L sp, -8(sp) + addi sp, sp, -(PT_SIZE_ON_STACK) + + //save context to overflow stack +diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c +index cd6f10c73a163..061117b8a3438 100644 +--- a/arch/riscv/kernel/traps.c ++++ b/arch/riscv/kernel/traps.c +@@ -408,48 +408,14 @@ int is_valid_bugaddr(unsigned long pc) + #endif /* CONFIG_GENERIC_BUG */ + + #ifdef CONFIG_VMAP_STACK +-/* +- * Extra stack space that allows us to provide panic messages when the kernel +- * has overflowed its stack. +- */ +-static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], ++DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], + overflow_stack)__aligned(16); +-/* +- * A temporary stack for use by handle_kernel_stack_overflow. This is used so +- * we can call into C code to get the per-hart overflow stack. Usage of this +- * stack must be protected by spin_shadow_stack. +- */ +-long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16); +- +-/* +- * A pseudo spinlock to protect the shadow stack from being used by multiple +- * harts concurrently. This isn't a real spinlock because the lock side must +- * be taken without a valid stack and only a single register, it's only taken +- * while in the process of panicing anyway so the performance and error +- * checking a proper spinlock gives us doesn't matter. +- */ +-unsigned long spin_shadow_stack; +- +-asmlinkage unsigned long get_overflow_stack(void) +-{ +- return (unsigned long)this_cpu_ptr(overflow_stack) + +- OVERFLOW_STACK_SIZE; +-} + + asmlinkage void handle_bad_stack(struct pt_regs *regs) + { + unsigned long tsk_stk = (unsigned long)current->stack; + unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack); + +- /* +- * We're done with the shadow stack by this point, as we're on the +- * overflow stack. Tell any other concurrent overflowing harts that +- * they can proceed with panicing by releasing the pseudo-spinlock. +- * +- * This pairs with an amoswap.aq in handle_kernel_stack_overflow. +- */ +- smp_store_release(&spin_shadow_stack, 0); +- + console_verbose(); + + pr_emerg("Insufficient stack space to handle exception!\n"); +-- +2.42.0 + diff --git a/queue-6.5/samples-bpf-syscall_tp_user-fix-array-out-of-bound-a.patch b/queue-6.5/samples-bpf-syscall_tp_user-fix-array-out-of-bound-a.patch new file mode 100644 index 00000000000..cf1b66c0723 --- /dev/null +++ b/queue-6.5/samples-bpf-syscall_tp_user-fix-array-out-of-bound-a.patch @@ -0,0 +1,87 @@ +From 85d77ac629ccb2830f6d81ddc2219200e27febdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 16:42:20 -0500 +Subject: samples/bpf: syscall_tp_user: Fix array out-of-bound access + +From: Jinghao Jia + +[ Upstream commit 9220c3ef6fefbf18f24aeedb1142a642b3de0596 ] + +Commit 06744f24696e ("samples/bpf: Add openat2() enter/exit tracepoint +to syscall_tp sample") added two more eBPF programs to support the +openat2() syscall. However, it did not increase the size of the array +that holds the corresponding bpf_links. This leads to an out-of-bound +access on that array in the bpf_object__for_each_program loop and could +corrupt other variables on the stack. On our testing QEMU, it corrupts +the map1_fds array and causes the sample to fail: + + # ./syscall_tp + prog #0: map ids 4 5 + verify map:4 val: 5 + map_lookup failed: Bad file descriptor + +Dynamically allocate the array based on the number of programs reported +by libbpf to prevent similar inconsistencies in the future + +Fixes: 06744f24696e ("samples/bpf: Add openat2() enter/exit tracepoint to syscall_tp sample") +Signed-off-by: Jinghao Jia +Signed-off-by: Ruowen Qin +Signed-off-by: Jinghao Jia +Link: https://lore.kernel.org/r/20230917214220.637721-4-jinghao7@illinois.edu +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + samples/bpf/syscall_tp_user.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/samples/bpf/syscall_tp_user.c b/samples/bpf/syscall_tp_user.c +index 18c94c7e8a40e..7a09ac74fac07 100644 +--- a/samples/bpf/syscall_tp_user.c ++++ b/samples/bpf/syscall_tp_user.c +@@ -48,7 +48,7 @@ static void verify_map(int map_id) + static int test(char *filename, int nr_tests) + { + int map0_fds[nr_tests], map1_fds[nr_tests], fd, i, j = 0; +- struct bpf_link *links[nr_tests * 4]; ++ struct bpf_link **links = NULL; + struct bpf_object *objs[nr_tests]; + struct bpf_program *prog; + +@@ -60,6 +60,19 @@ static int test(char *filename, int nr_tests) + goto cleanup; + } + ++ /* One-time initialization */ ++ if (!links) { ++ int nr_progs = 0; ++ ++ bpf_object__for_each_program(prog, objs[i]) ++ nr_progs += 1; ++ ++ links = calloc(nr_progs * nr_tests, sizeof(struct bpf_link *)); ++ ++ if (!links) ++ goto cleanup; ++ } ++ + /* load BPF program */ + if (bpf_object__load(objs[i])) { + fprintf(stderr, "loading BPF object file failed\n"); +@@ -107,8 +120,12 @@ static int test(char *filename, int nr_tests) + } + + cleanup: +- for (j--; j >= 0; j--) +- bpf_link__destroy(links[j]); ++ if (links) { ++ for (j--; j >= 0; j--) ++ bpf_link__destroy(links[j]); ++ ++ free(links); ++ } + + for (i--; i >= 0; i--) + bpf_object__close(objs[i]); +-- +2.42.0 + diff --git a/queue-6.5/samples-bpf-syscall_tp_user-rename-num_progs-into-nr.patch b/queue-6.5/samples-bpf-syscall_tp_user-rename-num_progs-into-nr.patch new file mode 100644 index 00000000000..f8f6f491fc4 --- /dev/null +++ b/queue-6.5/samples-bpf-syscall_tp_user-rename-num_progs-into-nr.patch @@ -0,0 +1,97 @@ +From d38a2a77b09d871eba31cb28aee391437cbf9e1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 16:42:19 -0500 +Subject: samples/bpf: syscall_tp_user: Rename num_progs into nr_tests + +From: Jinghao Jia + +[ Upstream commit 0ee352fe0d28015cab161b04d202fa3231c0ba3b ] + +The variable name num_progs causes confusion because that variable +really controls the number of rounds the test should be executed. + +Rename num_progs into nr_tests for the sake of clarity. + +Signed-off-by: Jinghao Jia +Signed-off-by: Ruowen Qin +Signed-off-by: Jinghao Jia +Link: https://lore.kernel.org/r/20230917214220.637721-3-jinghao7@illinois.edu +Signed-off-by: Alexei Starovoitov +Stable-dep-of: 9220c3ef6fef ("samples/bpf: syscall_tp_user: Fix array out-of-bound access") +Signed-off-by: Sasha Levin +--- + samples/bpf/syscall_tp_user.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/samples/bpf/syscall_tp_user.c b/samples/bpf/syscall_tp_user.c +index 7a788bb837fc1..18c94c7e8a40e 100644 +--- a/samples/bpf/syscall_tp_user.c ++++ b/samples/bpf/syscall_tp_user.c +@@ -17,9 +17,9 @@ + + static void usage(const char *cmd) + { +- printf("USAGE: %s [-i num_progs] [-h]\n", cmd); +- printf(" -i num_progs # number of progs of the test\n"); +- printf(" -h # help\n"); ++ printf("USAGE: %s [-i nr_tests] [-h]\n", cmd); ++ printf(" -i nr_tests # rounds of test to run\n"); ++ printf(" -h # help\n"); + } + + static void verify_map(int map_id) +@@ -45,14 +45,14 @@ static void verify_map(int map_id) + } + } + +-static int test(char *filename, int num_progs) ++static int test(char *filename, int nr_tests) + { +- int map0_fds[num_progs], map1_fds[num_progs], fd, i, j = 0; +- struct bpf_link *links[num_progs * 4]; +- struct bpf_object *objs[num_progs]; ++ int map0_fds[nr_tests], map1_fds[nr_tests], fd, i, j = 0; ++ struct bpf_link *links[nr_tests * 4]; ++ struct bpf_object *objs[nr_tests]; + struct bpf_program *prog; + +- for (i = 0; i < num_progs; i++) { ++ for (i = 0; i < nr_tests; i++) { + objs[i] = bpf_object__open_file(filename, NULL); + if (libbpf_get_error(objs[i])) { + fprintf(stderr, "opening BPF object file failed\n"); +@@ -101,7 +101,7 @@ static int test(char *filename, int num_progs) + close(fd); + + /* verify the map */ +- for (i = 0; i < num_progs; i++) { ++ for (i = 0; i < nr_tests; i++) { + verify_map(map0_fds[i]); + verify_map(map1_fds[i]); + } +@@ -117,13 +117,13 @@ static int test(char *filename, int num_progs) + + int main(int argc, char **argv) + { +- int opt, num_progs = 1; ++ int opt, nr_tests = 1; + char filename[256]; + + while ((opt = getopt(argc, argv, "i:h")) != -1) { + switch (opt) { + case 'i': +- num_progs = atoi(optarg); ++ nr_tests = atoi(optarg); + break; + case 'h': + default: +@@ -134,5 +134,5 @@ int main(int argc, char **argv) + + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); + +- return test(filename, num_progs); ++ return test(filename, nr_tests); + } +-- +2.42.0 + diff --git a/queue-6.5/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch b/queue-6.5/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch new file mode 100644 index 00000000000..da0c313f39a --- /dev/null +++ b/queue-6.5/sched-core-optimize-in_task-and-in_interrupt-a-bit.patch @@ -0,0 +1,100 @@ +From 66b2eab113eb64e0bac12a943e3a60a4af8fee27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 15:47:11 +1000 +Subject: sched/core: Optimize in_task() and in_interrupt() a bit + +From: Finn Thain + +[ Upstream commit 87c3a5893e865739ce78aa7192d36011022e0af7 ] + +Except on x86, preempt_count is always accessed with READ_ONCE(). +Repeated invocations in macros like irq_count() produce repeated loads. +These redundant instructions appear in various fast paths. In the one +shown below, for example, irq_count() is evaluated during kernel entry +if !tick_nohz_full_cpu(smp_processor_id()). + +0001ed0a : + 1ed0a: 4e56 0000 linkw %fp,#0 + 1ed0e: 200f movel %sp,%d0 + 1ed10: 0280 ffff e000 andil #-8192,%d0 + 1ed16: 2040 moveal %d0,%a0 + 1ed18: 2028 0008 movel %a0@(8),%d0 + 1ed1c: 0680 0001 0000 addil #65536,%d0 + 1ed22: 2140 0008 movel %d0,%a0@(8) + 1ed26: 082a 0001 000f btst #1,%a2@(15) + 1ed2c: 670c beqs 1ed3a + 1ed2e: 2028 0008 movel %a0@(8),%d0 + 1ed32: 2028 0008 movel %a0@(8),%d0 + 1ed36: 2028 0008 movel %a0@(8),%d0 + 1ed3a: 4e5e unlk %fp + 1ed3c: 4e75 rts + +This patch doesn't prevent the pointless btst and beqs instructions +above, but it does eliminate 2 of the 3 pointless move instructions +here and elsewhere. + +On x86, preempt_count is per-cpu data and the problem does not arise +presumably because the compiler is free to optimize more effectively. + +This patch was tested on m68k and x86. I was expecting no changes +to object code for x86 and mostly that's what I saw. However, there +were a few places where code generation was perturbed for some reason. + +The performance issue addressed here is minor on uniprocessor m68k. I +got a 0.01% improvement from this patch for a simple "find /sys -false" +benchmark. For architectures and workloads susceptible to cache line bounce +the improvement is expected to be larger. The only SMP architecture I have +is x86, and as x86 unaffected I have not done any further measurements. + +Fixes: 15115830c887 ("preempt: Cleanup the macro maze a bit") +Signed-off-by: Finn Thain +Signed-off-by: Ingo Molnar +Link: https://lore.kernel.org/r/0a403120a682a525e6db2d81d1a3ffcc137c3742.1694756831.git.fthain@linux-m68k.org +Signed-off-by: Sasha Levin +--- + include/linux/preempt.h | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/include/linux/preempt.h b/include/linux/preempt.h +index 1424670df161d..9aa6358a1a16b 100644 +--- a/include/linux/preempt.h ++++ b/include/linux/preempt.h +@@ -99,14 +99,21 @@ static __always_inline unsigned char interrupt_context_level(void) + return level; + } + ++/* ++ * These macro definitions avoid redundant invocations of preempt_count() ++ * because such invocations would result in redundant loads given that ++ * preempt_count() is commonly implemented with READ_ONCE(). ++ */ ++ + #define nmi_count() (preempt_count() & NMI_MASK) + #define hardirq_count() (preempt_count() & HARDIRQ_MASK) + #ifdef CONFIG_PREEMPT_RT + # define softirq_count() (current->softirq_disable_cnt & SOFTIRQ_MASK) ++# define irq_count() ((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | softirq_count()) + #else + # define softirq_count() (preempt_count() & SOFTIRQ_MASK) ++# define irq_count() (preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK)) + #endif +-#define irq_count() (nmi_count() | hardirq_count() | softirq_count()) + + /* + * Macros to retrieve the current execution context: +@@ -119,7 +126,11 @@ static __always_inline unsigned char interrupt_context_level(void) + #define in_nmi() (nmi_count()) + #define in_hardirq() (hardirq_count()) + #define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) +-#define in_task() (!(in_nmi() | in_hardirq() | in_serving_softirq())) ++#ifdef CONFIG_PREEMPT_RT ++# define in_task() (!((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | in_serving_softirq())) ++#else ++# define in_task() (!(preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) ++#endif + + /* + * The following macros are deprecated and should not be used in new code: +-- +2.42.0 + diff --git a/queue-6.5/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch b/queue-6.5/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch new file mode 100644 index 00000000000..23b6d6b6997 --- /dev/null +++ b/queue-6.5/scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch @@ -0,0 +1,110 @@ +From 21b46362820b8d1e0d50b51cc8daf38eb54ab02f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 10:15:25 +0800 +Subject: scsi: hisi_sas: Set debugfs_dir pointer to NULL after removing + debugfs + +From: Yihang Li + +[ Upstream commit 6de426f9276c448e2db7238911c97fb157cb23be ] + +If init debugfs failed during device registration due to memory allocation +failure, debugfs_remove_recursive() is called, after which debugfs_dir is +not set to NULL. debugfs_remove_recursive() will be called again during +device removal. As a result, illegal pointer is accessed. + +[ 1665.467244] hisi_sas_v3_hw 0000:b4:02.0: failed to init debugfs! +... +[ 1669.836708] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0 +[ 1669.872669] pc : down_write+0x24/0x70 +[ 1669.876315] lr : down_write+0x1c/0x70 +[ 1669.879961] sp : ffff000036f53a30 +[ 1669.883260] x29: ffff000036f53a30 x28: ffffa027c31549f8 +[ 1669.888547] x27: ffffa027c3140000 x26: 0000000000000000 +[ 1669.893834] x25: ffffa027bf37c270 x24: ffffa027bf37c270 +[ 1669.899122] x23: ffff0000095406b8 x22: ffff0000095406a8 +[ 1669.904408] x21: 0000000000000000 x20: ffffa027bf37c310 +[ 1669.909695] x19: 00000000000000a0 x18: ffff8027dcd86f10 +[ 1669.914982] x17: 0000000000000000 x16: 0000000000000000 +[ 1669.920268] x15: 0000000000000000 x14: ffffa0274014f870 +[ 1669.925555] x13: 0000000000000040 x12: 0000000000000228 +[ 1669.930842] x11: 0000000000000020 x10: 0000000000000bb0 +[ 1669.936129] x9 : ffff000036f537f0 x8 : ffff80273088ca10 +[ 1669.941416] x7 : 000000000000001d x6 : 00000000ffffffff +[ 1669.946702] x5 : ffff000008a36310 x4 : ffff80273088be00 +[ 1669.951989] x3 : ffff000009513e90 x2 : 0000000000000000 +[ 1669.957276] x1 : 00000000000000a0 x0 : ffffffff00000001 +[ 1669.962563] Call trace: +[ 1669.965000] down_write+0x24/0x70 +[ 1669.968301] debugfs_remove_recursive+0x5c/0x1b0 +[ 1669.972905] hisi_sas_debugfs_exit+0x24/0x30 [hisi_sas_main] +[ 1669.978541] hisi_sas_v3_remove+0x130/0x150 [hisi_sas_v3_hw] +[ 1669.984175] pci_device_remove+0x48/0xd8 +[ 1669.988082] device_release_driver_internal+0x1b4/0x250 +[ 1669.993282] device_release_driver+0x28/0x38 +[ 1669.997534] pci_stop_bus_device+0x84/0xb8 +[ 1670.001611] pci_stop_and_remove_bus_device_locked+0x24/0x40 +[ 1670.007244] remove_store+0xfc/0x140 +[ 1670.010802] dev_attr_store+0x44/0x60 +[ 1670.014448] sysfs_kf_write+0x58/0x80 +[ 1670.018095] kernfs_fop_write+0xe8/0x1f0 +[ 1670.022000] __vfs_write+0x60/0x190 +[ 1670.025472] vfs_write+0xac/0x1c0 +[ 1670.028771] ksys_write+0x6c/0xd8 +[ 1670.032071] __arm64_sys_write+0x24/0x30 +[ 1670.035977] el0_svc_common+0x78/0x130 +[ 1670.039710] el0_svc_handler+0x38/0x78 +[ 1670.043442] el0_svc+0x8/0xc + +To fix this, set debugfs_dir to NULL after debugfs_remove_recursive(). + +Signed-off-by: Yihang Li +Signed-off-by: Xingui Yang +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1694571327-78697-2-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 2f33e6b4a92fb..9285ae508afa6 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -4861,6 +4861,12 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS; + } + ++static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ hisi_hba->debugfs_dir = NULL; ++} ++ + static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +@@ -4884,18 +4890,13 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + + for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { + if (debugfs_alloc_v3_hw(hisi_hba, i)) { +- debugfs_remove_recursive(hisi_hba->debugfs_dir); ++ debugfs_exit_v3_hw(hisi_hba); + dev_dbg(dev, "failed to init debugfs!\n"); + break; + } + } + } + +-static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) +-{ +- debugfs_remove_recursive(hisi_hba->debugfs_dir); +-} +- + static int + hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { +-- +2.42.0 + diff --git a/queue-6.5/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch b/queue-6.5/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch new file mode 100644 index 00000000000..c71316b34e2 --- /dev/null +++ b/queue-6.5/scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch @@ -0,0 +1,322 @@ +From a8548c613451f32b185d007055ab9d9f352d083c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 17:54:25 -0500 +Subject: scsi: ibmvfc: Remove BUG_ON in the case of an empty event pool + +From: Tyrel Datwyler + +[ Upstream commit b39f2d10b86d0af353ea339e5815820026bca48f ] + +In practice the driver should never send more commands than are allocated +to a queue's event pool. In the unlikely event that this happens, the code +asserts a BUG_ON, and in the case that the kernel is not configured to +crash on panic returns a junk event pointer from the empty event list +causing things to spiral from there. This BUG_ON is a historical artifact +of the ibmvfc driver first being upstreamed, and it is well known now that +the use of BUG_ON is bad practice except in the most unrecoverable +scenario. There is nothing about this scenario that prevents the driver +from recovering and carrying on. + +Remove the BUG_ON in question from ibmvfc_get_event() and return a NULL +pointer in the case of an empty event pool. Update all call sites to +ibmvfc_get_event() to check for a NULL pointer and perfrom the appropriate +failure or recovery action. + +Signed-off-by: Tyrel Datwyler +Link: https://lore.kernel.org/r/20230921225435.3537728-2-tyreld@linux.ibm.com +Reviewed-by: Brian King +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/ibmvscsi/ibmvfc.c | 124 ++++++++++++++++++++++++++++++++- + 1 file changed, 122 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c +index 470e8e6c41b62..c98346e464b48 100644 +--- a/drivers/scsi/ibmvscsi/ibmvfc.c ++++ b/drivers/scsi/ibmvscsi/ibmvfc.c +@@ -1518,7 +1518,11 @@ static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_queue *queue) + unsigned long flags; + + spin_lock_irqsave(&queue->l_lock, flags); +- BUG_ON(list_empty(&queue->free)); ++ if (list_empty(&queue->free)) { ++ ibmvfc_log(queue->vhost, 4, "empty event pool on queue:%ld\n", queue->hwq_id); ++ spin_unlock_irqrestore(&queue->l_lock, flags); ++ return NULL; ++ } + evt = list_entry(queue->free.next, struct ibmvfc_event, queue_list); + atomic_set(&evt->free, 0); + list_del(&evt->queue_list); +@@ -1947,9 +1951,15 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) + if (vhost->using_channels) { + scsi_channel = hwq % vhost->scsi_scrqs.active_queues; + evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[scsi_channel]); ++ if (!evt) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ + evt->hwq = hwq % vhost->scsi_scrqs.active_queues; +- } else ++ } else { + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ } + + ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT); + evt->cmnd = cmnd; +@@ -2037,6 +2047,11 @@ static int ibmvfc_bsg_timeout(struct bsg_job *job) + + vhost->aborting_passthru = 1; + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } ++ + ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT); + + tmf = &evt->iu.tmf; +@@ -2095,6 +2110,10 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id) + goto unlock_out; + + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ rc = -ENOMEM; ++ goto unlock_out; ++ } + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + plogi = &evt->iu.plogi; + memset(plogi, 0, sizeof(*plogi)); +@@ -2213,6 +2232,11 @@ static int ibmvfc_bsg_request(struct bsg_job *job) + } + + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ rc = -ENOMEM; ++ goto out; ++ } + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + mad = &evt->iu.passthru; + +@@ -2301,6 +2325,11 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) + else + evt = ibmvfc_get_event(&vhost->crq); + ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } ++ + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); + tmf = ibmvfc_init_vfc_cmd(evt, sdev); + iu = ibmvfc_get_fcp_iu(vhost, tmf); +@@ -2504,6 +2533,8 @@ static struct ibmvfc_event *ibmvfc_init_tmf(struct ibmvfc_queue *queue, + struct ibmvfc_tmf *tmf; + + evt = ibmvfc_get_event(queue); ++ if (!evt) ++ return NULL; + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); + + tmf = &evt->iu.tmf; +@@ -2560,6 +2591,11 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type) + + if (found_evt && vhost->logged_in) { + evt = ibmvfc_init_tmf(&queues[i], sdev, type); ++ if (!evt) { ++ spin_unlock(queues[i].q_lock); ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } + evt->sync_iu = &queues[i].cancel_rsp; + ibmvfc_send_event(evt, vhost, default_timeout); + list_add_tail(&evt->cancel, &cancelq); +@@ -2773,6 +2809,10 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) + + if (vhost->state == IBMVFC_ACTIVE) { + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return -ENOMEM; ++ } + ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); + tmf = ibmvfc_init_vfc_cmd(evt, sdev); + iu = ibmvfc_get_fcp_iu(vhost, tmf); +@@ -4031,6 +4071,12 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; +@@ -4138,6 +4184,12 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) + kref_get(&tgt->kref); + tgt->logo_rcvd = 0; + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT); +@@ -4214,6 +4266,8 @@ static struct ibmvfc_event *__ibmvfc_tgt_get_implicit_logout_evt(struct ibmvfc_t + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) ++ return NULL; + ibmvfc_init_event(evt, done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; + mad = &evt->iu.implicit_logout; +@@ -4241,6 +4295,13 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) + vhost->discovery_threads++; + evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt, + ibmvfc_tgt_implicit_logout_done); ++ if (!evt) { ++ vhost->discovery_threads--; ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + if (ibmvfc_send_event(evt, vhost, default_timeout)) { +@@ -4380,6 +4441,12 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); + ibmvfc_init_event(evt, ibmvfc_tgt_move_login_done, IBMVFC_MAD_FORMAT); +@@ -4546,6 +4613,14 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) + vhost->abort_threads++; + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ tgt_err(tgt, "Failed to get cancel event for ADISC.\n"); ++ vhost->abort_threads--; ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ spin_unlock_irqrestore(vhost->host->host_lock, flags); ++ return; ++ } + ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT); + + evt->tgt = tgt; +@@ -4596,6 +4671,12 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); + evt->tgt = tgt; +@@ -4699,6 +4780,12 @@ static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt) + + kref_get(&tgt->kref); + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); ++ kref_put(&tgt->kref, ibmvfc_release_tgt); ++ __ibmvfc_reset_host(vhost); ++ return; ++ } + vhost->discovery_threads++; + evt->tgt = tgt; + ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT); +@@ -4871,6 +4958,13 @@ static void ibmvfc_discover_targets(struct ibmvfc_host *vhost) + { + struct ibmvfc_discover_targets *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); ++ int level = IBMVFC_DEFAULT_LOG_LEVEL; ++ ++ if (!evt) { ++ ibmvfc_log(vhost, level, "Discover Targets failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } + + ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT); + mad = &evt->iu.discover_targets; +@@ -4948,8 +5042,15 @@ static void ibmvfc_channel_setup(struct ibmvfc_host *vhost) + struct ibmvfc_scsi_channels *scrqs = &vhost->scsi_scrqs; + unsigned int num_channels = + min(vhost->client_scsi_channels, vhost->max_vios_scsi_channels); ++ int level = IBMVFC_DEFAULT_LOG_LEVEL; + int i; + ++ if (!evt) { ++ ibmvfc_log(vhost, level, "Channel Setup failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } ++ + memset(setup_buf, 0, sizeof(*setup_buf)); + if (num_channels == 0) + setup_buf->flags = cpu_to_be32(IBMVFC_CANCEL_CHANNELS); +@@ -5011,6 +5112,13 @@ static void ibmvfc_channel_enquiry(struct ibmvfc_host *vhost) + { + struct ibmvfc_channel_enquiry *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); ++ int level = IBMVFC_DEFAULT_LOG_LEVEL; ++ ++ if (!evt) { ++ ibmvfc_log(vhost, level, "Channel Enquiry failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } + + ibmvfc_init_event(evt, ibmvfc_channel_enquiry_done, IBMVFC_MAD_FORMAT); + mad = &evt->iu.channel_enquiry; +@@ -5133,6 +5241,12 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost) + struct ibmvfc_npiv_login_mad *mad; + struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); + ++ if (!evt) { ++ ibmvfc_dbg(vhost, "NPIV Login failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } ++ + ibmvfc_gather_partition_info(vhost); + ibmvfc_set_login_info(vhost); + ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT); +@@ -5197,6 +5311,12 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *vhost) + struct ibmvfc_event *evt; + + evt = ibmvfc_get_event(&vhost->crq); ++ if (!evt) { ++ ibmvfc_dbg(vhost, "NPIV Logout failed: no available events\n"); ++ ibmvfc_hard_reset_host(vhost); ++ return; ++ } ++ + ibmvfc_init_event(evt, ibmvfc_npiv_logout_done, IBMVFC_MAD_FORMAT); + + mad = &evt->iu.npiv_logout; +-- +2.42.0 + diff --git a/queue-6.5/scsi-libfc-fix-potential-null-pointer-dereference-in.patch b/queue-6.5/scsi-libfc-fix-potential-null-pointer-dereference-in.patch new file mode 100644 index 00000000000..fc9cbf73fbf --- /dev/null +++ b/queue-6.5/scsi-libfc-fix-potential-null-pointer-dereference-in.patch @@ -0,0 +1,44 @@ +From 91112a4863f849e4c5765c6c2f2e54e32ecd43b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 21:03:50 +0800 +Subject: scsi: libfc: Fix potential NULL pointer dereference in + fc_lport_ptp_setup() + +From: Wenchao Hao + +[ Upstream commit 4df105f0ce9f6f30cda4e99f577150d23f0c9c5f ] + +fc_lport_ptp_setup() did not check the return value of fc_rport_create() +which can return NULL and would cause a NULL pointer dereference. Address +this issue by checking return value of fc_rport_create() and log error +message on fc_rport_create() failed. + +Signed-off-by: Wenchao Hao +Link: https://lore.kernel.org/r/20231011130350.819571-1-haowenchao2@huawei.com +Reviewed-by: Simon Horman +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/libfc/fc_lport.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c +index 9c02c9523c4d4..ab06e9aeb613e 100644 +--- a/drivers/scsi/libfc/fc_lport.c ++++ b/drivers/scsi/libfc/fc_lport.c +@@ -241,6 +241,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, + } + mutex_lock(&lport->disc.disc_mutex); + lport->ptp_rdata = fc_rport_create(lport, remote_fid); ++ if (!lport->ptp_rdata) { ++ printk(KERN_WARNING "libfc: Failed to setup lport 0x%x\n", ++ lport->port_id); ++ mutex_unlock(&lport->disc.disc_mutex); ++ return; ++ } + kref_get(&lport->ptp_rdata->kref); + lport->ptp_rdata->ids.port_name = remote_wwpn; + lport->ptp_rdata->ids.node_name = remote_wwnn; +-- +2.42.0 + diff --git a/queue-6.5/scsi-ufs-core-expand-mcq-queue-slot-to-devicequeuede.patch b/queue-6.5/scsi-ufs-core-expand-mcq-queue-slot-to-devicequeuede.patch new file mode 100644 index 00000000000..80c0e667808 --- /dev/null +++ b/queue-6.5/scsi-ufs-core-expand-mcq-queue-slot-to-devicequeuede.patch @@ -0,0 +1,43 @@ +From 60b40f512a1a9404c4ed4d408417b062718e3c7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Nov 2023 13:24:24 +0800 +Subject: scsi: ufs: core: Expand MCQ queue slot to DeviceQueueDepth + 1 + +From: Naomi Chu + +[ Upstream commit defde5a50d91c74e1ce71a7f0bce7fb1ae311d84 ] + +The UFSHCI 4.0 specification mandates that there should always be at least +one empty slot in each queue for distinguishing between full and empty +states. Enlarge 'hwq->max_entries' to 'DeviceQueueDepth + 1' to allow +UFSHCI 4.0 controllers to fully utilize MCQ queue slots. + +Fixes: 4682abfae2eb ("scsi: ufs: core: mcq: Allocate memory for MCQ mode") +Signed-off-by: Naomi Chu +Link: https://lore.kernel.org/r/20231102052426.12006-2-naomi.chu@mediatek.com +Reviewed-by: Stanley Chu +Reviewed-by: Bart Van Assche +Reviewed-by: Peter Wang +Reviewed-by: Chun-Hung +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufs-mcq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c +index 386674ead7f0d..4ecbd30c07827 100644 +--- a/drivers/ufs/core/ufs-mcq.c ++++ b/drivers/ufs/core/ufs-mcq.c +@@ -433,7 +433,7 @@ int ufshcd_mcq_init(struct ufs_hba *hba) + + for (i = 0; i < hba->nr_hw_queues; i++) { + hwq = &hba->uhq[i]; +- hwq->max_entries = hba->nutrs; ++ hwq->max_entries = hba->nutrs + 1; + spin_lock_init(&hwq->sq_lock); + spin_lock_init(&hwq->cq_lock); + mutex_init(&hwq->sq_mutex); +-- +2.42.0 + diff --git a/queue-6.5/selftests-efivarfs-create-read-fix-a-resource-leak.patch b/queue-6.5/selftests-efivarfs-create-read-fix-a-resource-leak.patch new file mode 100644 index 00000000000..413e69f8404 --- /dev/null +++ b/queue-6.5/selftests-efivarfs-create-read-fix-a-resource-leak.patch @@ -0,0 +1,37 @@ +From afa44e68ac3113fd0e8a0a435357e40d2af08a40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 18:59:21 -0700 +Subject: selftests/efivarfs: create-read: fix a resource leak + +From: zhujun2 + +[ Upstream commit 3f6f8a8c5e11a9b384a36df4f40f0c9a653b6975 ] + +The opened file should be closed in main(), otherwise resource +leak will occur that this problem was discovered by code reading + +Signed-off-by: zhujun2 +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/efivarfs/create-read.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/testing/selftests/efivarfs/create-read.c b/tools/testing/selftests/efivarfs/create-read.c +index 9674a19396a32..7bc7af4eb2c17 100644 +--- a/tools/testing/selftests/efivarfs/create-read.c ++++ b/tools/testing/selftests/efivarfs/create-read.c +@@ -32,8 +32,10 @@ int main(int argc, char **argv) + rc = read(fd, buf, sizeof(buf)); + if (rc != 0) { + fprintf(stderr, "Reading a new var should return EOF\n"); ++ close(fd); + return EXIT_FAILURE; + } + ++ close(fd); + return EXIT_SUCCESS; + } +-- +2.42.0 + diff --git a/queue-6.5/selftests-lkdtm-disable-config_ubsan_trap-in-test-co.patch b/queue-6.5/selftests-lkdtm-disable-config_ubsan_trap-in-test-co.patch new file mode 100644 index 00000000000..6613fff6a45 --- /dev/null +++ b/queue-6.5/selftests-lkdtm-disable-config_ubsan_trap-in-test-co.patch @@ -0,0 +1,68 @@ +From 319c8f6b7009dc1aaaefe0370b99ed1846da3de3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Aug 2023 08:32:52 +0200 +Subject: selftests/lkdtm: Disable CONFIG_UBSAN_TRAP in test config +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ricardo Cañuelo + +[ Upstream commit cf77bf698887c3b9ebed76dea492b07a3c2c7632 ] + +The lkdtm selftest config fragment enables CONFIG_UBSAN_TRAP to make the +ARRAY_BOUNDS test kill the calling process when an out-of-bound access +is detected by UBSAN. However, after this [1] commit, UBSAN is triggered +under many new scenarios that weren't detected before, such as in struct +definitions with fixed-size trailing arrays used as flexible arrays. As +a result, CONFIG_UBSAN_TRAP=y has become a very aggressive option to +enable except for specific situations. + +`make kselftest-merge` applies CONFIG_UBSAN_TRAP=y to the kernel config +for all selftests, which makes many of them fail because of system hangs +during boot. + +This change removes the config option from the lkdtm kselftest and +configures the ARRAY_BOUNDS test to look for UBSAN reports rather than +relying on the calling process being killed. + +[1] commit 2d47c6956ab3 ("ubsan: Tighten UBSAN_BOUNDS on GCC")' + +Signed-off-by: Ricardo Cañuelo +Reviewed-by: Kees Cook +Link: https://lore.kernel.org/r/20230802063252.1917997-1-ricardo.canuelo@collabora.com +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/lkdtm/config | 1 - + tools/testing/selftests/lkdtm/tests.txt | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/lkdtm/config b/tools/testing/selftests/lkdtm/config +index 5d52f64dfb430..7afe05e8c4d79 100644 +--- a/tools/testing/selftests/lkdtm/config ++++ b/tools/testing/selftests/lkdtm/config +@@ -9,7 +9,6 @@ CONFIG_INIT_ON_FREE_DEFAULT_ON=y + CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y + CONFIG_UBSAN=y + CONFIG_UBSAN_BOUNDS=y +-CONFIG_UBSAN_TRAP=y + CONFIG_STACKPROTECTOR_STRONG=y + CONFIG_SLUB_DEBUG=y + CONFIG_SLUB_DEBUG_ON=y +diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt +index 607b8d7e3ea34..2f3a1b96da6e3 100644 +--- a/tools/testing/selftests/lkdtm/tests.txt ++++ b/tools/testing/selftests/lkdtm/tests.txt +@@ -7,7 +7,7 @@ EXCEPTION + #EXHAUST_STACK Corrupts memory on failure + #CORRUPT_STACK Crashes entire system on success + #CORRUPT_STACK_STRONG Crashes entire system on success +-ARRAY_BOUNDS ++ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds + CORRUPT_LIST_ADD list_add corruption + CORRUPT_LIST_DEL list_del corruption + STACK_GUARD_PAGE_LEADING +-- +2.42.0 + diff --git a/queue-6.5/series b/queue-6.5/series new file mode 100644 index 00000000000..ab724717f96 --- /dev/null +++ b/queue-6.5/series @@ -0,0 +1,222 @@ +locking-ww_mutex-test-fix-potential-workqueue-corrup.patch +btrfs-abort-transaction-on-generation-mismatch-when-.patch +lib-generic-radix-tree.c-don-t-overflow-in-peek.patch +x86-retpoline-make-sure-there-are-no-unconverted-ret.patch +perf-core-bail-out-early-if-the-request-aux-area-is-.patch +rcu-dump-memory-object-info-if-callback-function-is-.patch +srcu-fix-srcu_struct-node-grpmask-overflow-on-64-bit.patch +selftests-lkdtm-disable-config_ubsan_trap-in-test-co.patch +clocksource-drivers-timer-imx-gpt-fix-potential-memo.patch +clocksource-drivers-timer-atmel-tcb-fix-initializati.patch +srcu-only-accelerate-on-enqueue-time.patch +smp-csd-throw-an-error-if-a-csd-lock-is-stuck-for-to.patch +cpu-hotplug-don-t-offline-the-last-non-isolated-cpu.patch +workqueue-provide-one-lock-class-key-per-work_on_cpu.patch +x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch +wifi-plfxlc-fix-clang-specific-fortify-warning.patch +wifi-ath12k-ignore-fragments-from-uninitialized-peer.patch +wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch +wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch +atl1c-work-around-the-dma-rx-overflow-issue.patch +bpf-detect-ip-ksym.end-as-part-of-bpf-program.patch +wifi-ath9k-fix-clang-specific-fortify-warnings.patch +wifi-ath12k-fix-possible-out-of-bound-read-in-ath12k.patch +wifi-ath10k-fix-clang-specific-fortify-warning.patch +wifi-ath12k-fix-possible-out-of-bound-write-in-ath12.patch +acpi-apei-fix-aer-info-corruption-when-error-status-.patch +net-sfp-add-quirk-for-fiberstone-gpon-onu-34-20bi.patch +wifi-mt76-mt7921e-support-mt7992-ip-in-xiaomi-redmib.patch +net-annotate-data-races-around-sk-sk_tx_queue_mappin.patch +net-annotate-data-races-around-sk-sk_dst_pending_con.patch +wifi-ath12k-mhi-fix-potential-memory-leak-in-ath12k_.patch +wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch +net-sfp-add-quirk-for-fs-s-2.5g-copper-sfp.patch +vsock-read-from-socket-s-error-queue.patch +bpf-ensure-proper-register-state-printing-for-cond-j.patch +wifi-iwlwifi-mvm-fix-size-check-for-fw_link_id.patch +bluetooth-btusb-add-date-evt_skb-is-null-check.patch +bluetooth-fix-double-free-in-hci_conn_cleanup.patch +acpi-ec-add-quirk-for-hp-250-g7-notebook-pc.patch +tsnep-fix-tsnep_request_irq-format-overflow-warning.patch +gpiolib-acpi-add-a-ignore-interrupt-quirk-for-peaq-c.patch +platform-chrome-kunit-initialize-lock-for-fake-ec_de.patch +of-address-fix-address-translation-when-address-size.patch +platform-x86-thinkpad_acpi-add-battery-quirk-for-thi.patch +drm-gma500-fix-call-trace-when-psb_gem_mm_init-fails.patch +drm-amdkfd-ratelimited-sq-interrupt-messages.patch +drm-komeda-drop-all-currently-held-locks-if-deadlock.patch +drm-amd-display-blank-phantom-otg-before-enabling.patch +drm-amd-display-don-t-lock-phantom-pipe-on-disabling.patch +drm-amd-display-add-seamless-pipe-topology-transitio.patch +drm-edid-fixup-h-vsync_end-instead-of-h-vtotal.patch +md-don-t-rely-on-mddev-pers-to-be-set-in-mddev_suspe.patch +drm-amdgpu-not-to-save-bo-in-the-case-of-ras-err_eve.patch +drm-amdkfd-fix-a-race-condition-of-vram-buffer-unref.patch +drm-amd-update-update_pcie_parameters-functions-to-u.patch +drm-amd-display-use-full-update-for-clip-size-increa.patch +string.h-add-array-wrappers-for-v-memdup_user.patch +kernel-kexec-copy-user-array-safely.patch +kernel-watch_queue-copy-user-array-safely.patch +drm_lease.c-copy-user-array-safely.patch +drm-vmwgfx_surface.c-copy-user-array-safely.patch +drm-msm-dp-skip-validity-check-for-dp-cts-edid-check.patch +drm-amd-fix-ubsan-array-index-out-of-bounds-for-smu7.patch +drm-amd-fix-ubsan-array-index-out-of-bounds-for-pola.patch +drm-amdgpu-fix-potential-null-pointer-derefernce.patch +drm-panel-fix-a-possible-null-pointer-dereference.patch +drm-panel-panel-tpo-tpg110-fix-a-possible-null-point.patch +drm-radeon-fix-a-possible-null-pointer-dereference.patch +drm-amdgpu-vkms-fix-a-possible-null-pointer-derefere.patch +drm-panel-st7703-pick-different-reset-sequence.patch +drm-amdkfd-fix-shift-out-of-bounds-issue.patch +drm-amdgpu-fix-a-null-pointer-access-when-the-smc_rr.patch +drm-amd-disable-pp_pcie_dpm_mask-when-dynamic-speed-.patch +drm-amd-display-fix-num_ways-overflow-error.patch +drm-amd-check-num-of-link-levels-when-update-pcie-pa.patch +arm64-dts-ls208xa-use-a-pseudo-bus-to-constrain-usb-.patch +selftests-efivarfs-create-read-fix-a-resource-leak.patch +asoc-mediatek-mt8188-mt6359-support-dynamic-pinctrl.patch +asoc-soc-card-add-storage-for-pci-ssid.patch +asoc-sof-pass-pci-ssid-to-machine-driver.patch +crypto-pcrypt-fix-hungtask-for-padata_reset.patch +alsa-scarlett2-move-usb-ids-out-from-device_info-str.patch +asoc-sof-ipc4-handle-exception_caught-notification-f.patch +rdma-hfi1-use-field_get-to-extract-link-width.patch +scsi-hisi_sas-set-debugfs_dir-pointer-to-null-after-.patch +scsi-ibmvfc-remove-bug_on-in-the-case-of-an-empty-ev.patch +fs-jfs-add-check-for-negative-db_l2nbperpage.patch +fs-jfs-add-validity-check-for-db_maxag-and-db_agpref.patch +jfs-fix-array-index-out-of-bounds-in-dbfindleaf.patch +jfs-fix-array-index-out-of-bounds-in-dialloc.patch +hid-lenovo-detect-quirk-free-fw-on-cptkbd-and-stop-a.patch +arm-9320-1-fix-stack-depot-irq-stack-filter.patch +alsa-hda-fix-possible-null-ptr-deref-when-assigning-.patch +gpiolib-of-add-quirk-for-mt2701-cs42448-asoc-sound.patch +pci-tegra194-use-field_get-field_prep-with-link-widt.patch +pci-mvebu-use-field_prep-with-link-width.patch +atm-iphase-do-pci-error-checks-on-own-line.patch +pci-do-error-check-on-own-line-to-split-long-if-cond.patch +scsi-libfc-fix-potential-null-pointer-dereference-in.patch +pci-use-field_get-to-extract-link-width.patch +pci-extract-ats-disabling-to-a-helper-function.patch +pci-disable-ats-for-specific-intel-ipu-e2000-devices.patch +pci-dwc-add-dw_pcie_link_set_max_link_width.patch +pci-dwc-add-missing-pci_exp_lnkcap_mlw-handling.patch +misc-pci_endpoint_test-add-device-id-for-r-car-s4-8-.patch +pci-use-field_get-in-sapphire-rx-5600-xt-pulse-quirk.patch +asoc-intel-soc-acpi-cht-add-lenovo-yoga-tab-3-pro-yt.patch +crypto-hisilicon-qm-prevent-soft-lockup-in-receive-l.patch +hid-add-quirk-for-dell-pro-wireless-keyboard-and-mou.patch +exfat-support-handle-zero-size-directory.patch +mfd-intel-lpss-add-intel-lunar-lake-m-pci-ids.patch +iio-adc-stm32-adc-harden-against-null-pointer-deref-.patch +thunderbolt-apply-usb-3.x-bandwidth-quirk-only-in-so.patch +tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch +dt-bindings-phy-qcom-snps-eusb2-repeater-add-magic-t.patch +phy-qualcomm-phy-qcom-eusb2-repeater-use-regmap_fiel.patch +phy-qualcomm-phy-qcom-eusb2-repeater-zero-out-untouc.patch +usb-dwc3-core-configure-tx-rx-threshold-for-dwc3_ip.patch +usb-ucsi-glink-use-the-connector-orientation-gpio-to.patch +soundwire-dmi-quirks-update-hp-omen-match.patch +f2fs-fix-error-path-of-__f2fs_build_free_nids.patch +f2fs-fix-error-handling-of-__get_node_page.patch +usb-host-xhci-avoid-xhci-resume-delay-if-ssusb-devic.patch +usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch +9p-trans_fd-annotate-data-racy-writes-to-file-f_flag.patch +9p-v9fs_listxattr-fix-s-null-argument-warning.patch +i3c-mipi-i3c-hci-fix-out-of-bounds-access-in-hci_dma.patch +i2c-i801-add-support-for-intel-birch-stream-soc.patch +i2c-fix-memleak-in-i2c_new_client_device.patch +i2c-sun6i-p2wi-prevent-potential-division-by-zero.patch +virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch +i3c-master-mipi-i3c-hci-fix-a-kernel-panic-for-acces.patch +media-gspca-cpia1-shift-out-of-bounds-in-set_flicker.patch +media-vivid-avoid-integer-overflow.patch +media-ipu-bridge-increase-sensor_name-size.patch +gfs2-ignore-negated-quota-changes.patch +gfs2-fix-an-oops-in-gfs2_permission.patch +media-cobalt-use-field_get-to-extract-link-width.patch +media-ccs-fix-driver-quirk-struct-documentation.patch +media-imon-fix-access-to-invalid-resource-for-the-se.patch +drm-amd-display-avoid-null-dereference-of-timing-gen.patch +kgdb-flush-console-before-entering-kgdb-on-panic.patch +riscv-vmap_stack-overflow-detection-thread-safe.patch +i2c-dev-copy-userspace-array-safely.patch +asoc-ti-omap-mcbsp-fix-runtime-pm-underflow-warnings.patch +drm-qxl-prevent-memory-leak.patch +alsa-hda-realtek-add-quirk-for-asus-ux7602zm.patch +drm-amdgpu-fix-software-pci_unplug-on-some-chips.patch +pwm-fix-double-shift-bug.patch +mtd-rawnand-tegra-add-missing-check-for-platform_get.patch +wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch +sched-core-optimize-in_task-and-in_interrupt-a-bit.patch +samples-bpf-syscall_tp_user-rename-num_progs-into-nr.patch +samples-bpf-syscall_tp_user-fix-array-out-of-bound-a.patch +dt-bindings-serial-fix-regex-pattern-for-matching-se.patch +sunrpc-econnreset-might-require-a-rebind.patch +mtd-rawnand-intel-check-return-value-of-devm_kasprin.patch +mtd-rawnand-meson-check-return-value-of-devm_kasprin.patch +drm-i915-mtl-avoid-stringop-overflow-warning.patch +nfsv4.1-fix-handling-nfs4err_delay-when-testing-for-.patch +sunrpc-add-an-is_err-check-back-to-where-it-was.patch +nfsv4.1-fix-sp4_mach_cred-protection-for-pnfs-io.patch +sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch +risc-v-hwprobe-fix-vdso-sigsegv.patch +riscv-provide-riscv-specific-is_trap_insn.patch +gfs2-silence-suspicious-rcu-usage-in-gfs2_permission.patch +drm-i915-tc-fix-wformat-truncation-in-intel_tc_port_.patch +vdpa_sim_blk-allocate-the-buffer-zeroed.patch +vhost-vdpa-fix-use-after-free-in-vhost_vdpa_probe.patch +gcc-plugins-randstruct-only-warn-about-true-flexible.patch +bpf-handle-ldimm64-properly-in-check_cfg.patch +bpf-fix-precision-backtracking-instruction-iteration.patch +net-set-sock_rcu_free-before-inserting-socket-into-h.patch +ipvlan-add-ipvlan_route_v6_outbound-helper.patch +tty-fix-uninit-value-access-in-ppp_sync_receive.patch +xen-events-avoid-using-info_for_irq-in-xen_send_ipi_.patch +net-hns3-fix-add-vlan-fail-issue.patch +net-hns3-add-barrier-in-vf-mailbox-reply-process.patch +net-hns3-fix-incorrect-capability-bit-display-for-co.patch +net-hns3-fix-out-of-bounds-access-may-occur-when-coa.patch +net-hns3-fix-variable-may-not-initialized-problem-in.patch +net-hns3-fix-vf-reset-fail-issue.patch +net-hns3-fix-vf-wrong-speed-and-duplex-issue.patch +tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch +net-mvneta-fix-calls-to-page_pool_get_stats.patch +ppp-limit-mru-to-64k.patch +xen-events-fix-delayed-eoi-list-handling.patch +blk-mq-make-sure-active-queue-usage-is-held-for-bio_.patch +ptp-annotate-data-race-around-q-head-and-q-tail.patch +bonding-stop-the-device-in-bond_setup_by_slave.patch +net-ethernet-cortina-fix-max-rx-frame-define.patch +net-ethernet-cortina-handle-large-frames.patch +net-ethernet-cortina-fix-mtu-max-setting.patch +af_unix-fix-use-after-free-in-unix_stream_read_actor.patch +netfilter-nf_conntrack_bridge-initialize-err-to-0.patch +netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch +netfilter-nf_tables-bogus-enoent-when-destroying-ele.patch +net-stmmac-fix-rx-budget-limit-check.patch +net-stmmac-avoid-rx-queue-overrun.patch +pds_core-use-correct-index-to-mask-irq.patch +pds_core-fix-up-some-format-truncation-complaints.patch +gve-fixes-for-napi_poll-when-budget-is-0.patch +io_uring-fdinfo-remove-need-for-sqpoll-lock-for-thre.patch +net-mlx5-decouple-phc-.adjtime-and-.adjphase-impleme.patch +net-mlx5e-fix-double-free-of-encap_header.patch +net-mlx5e-fix-double-free-of-encap_header-in-update-.patch +net-mlx5e-fix-pedit-endianness.patch +net-mlx5-consolidate-devlink-documentation-in-devlin.patch +net-mlx5e-make-tx_port_ts-logic-resilient-to-out-of-.patch +net-mlx5e-add-recovery-flow-for-tx-devlink-health-re.patch +net-mlx5e-update-doorbell-for-port-timestamping-cq-b.patch +net-mlx5-increase-size-of-irq-name-buffer.patch +net-mlx5e-reduce-the-size-of-icosq_str.patch +net-mlx5e-check-return-value-of-snprintf-writing-to-.patch +net-mlx5e-check-return-value-of-snprintf-writing-to-.patch-24193 +net-sched-do-not-offload-flows-with-a-helper-in-act_.patch +macvlan-don-t-propagate-promisc-change-to-lower-dev-.patch +tools-power-turbostat-fix-a-knl-bug.patch +tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch +scsi-ufs-core-expand-mcq-queue-slot-to-devicequeuede.patch +cifs-spnego-add-in-host_key_len.patch +cifs-fix-check-of-rc-in-function-generate_smb3signin.patch diff --git a/queue-6.5/smp-csd-throw-an-error-if-a-csd-lock-is-stuck-for-to.patch b/queue-6.5/smp-csd-throw-an-error-if-a-csd-lock-is-stuck-for-to.patch new file mode 100644 index 00000000000..e143f45a568 --- /dev/null +++ b/queue-6.5/smp-csd-throw-an-error-if-a-csd-lock-is-stuck-for-to.patch @@ -0,0 +1,105 @@ +From 34d97f7deaa3cc7fe0f915b0264c34f8c3825fa7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Aug 2023 16:04:09 -0400 +Subject: smp,csd: Throw an error if a CSD lock is stuck for too long + +From: Rik van Riel + +[ Upstream commit 94b3f0b5af2c7af69e3d6e0cdd9b0ea535f22186 ] + +The CSD lock seems to get stuck in 2 "modes". When it gets stuck +temporarily, it usually gets released in a few seconds, and sometimes +up to one or two minutes. + +If the CSD lock stays stuck for more than several minutes, it never +seems to get unstuck, and gradually more and more things in the system +end up also getting stuck. + +In the latter case, we should just give up, so the system can dump out +a little more information about what went wrong, and, with panic_on_oops +and a kdump kernel loaded, dump a whole bunch more information about what +might have gone wrong. In addition, there is an smp.panic_on_ipistall +kernel boot parameter that by default retains the old behavior, but when +set enables the panic after the CSD lock has been stuck for more than +the specified number of milliseconds, as in 300,000 for five minutes. + +[ paulmck: Apply Imran Khan feedback. ] +[ paulmck: Apply Leonardo Bras feedback. ] + +Link: https://lore.kernel.org/lkml/bc7cc8b0-f587-4451-8bcd-0daae627bcc7@paulmck-laptop/ +Signed-off-by: Rik van Riel +Signed-off-by: Paul E. McKenney +Reviewed-by: Imran Khan +Reviewed-by: Leonardo Bras +Cc: Peter Zijlstra +Cc: Valentin Schneider +Cc: Juergen Gross +Cc: Jonathan Corbet +Cc: Randy Dunlap +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 7 +++++++ + kernel/smp.c | 13 ++++++++++++- + 2 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 23ebe34ff901e..b951b4c2808f1 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -5781,6 +5781,13 @@ + This feature may be more efficiently disabled + using the csdlock_debug- kernel parameter. + ++ smp.panic_on_ipistall= [KNL] ++ If a csd_lock_timeout extends for more than ++ the specified number of milliseconds, panic the ++ system. By default, let CSD-lock acquisition ++ take as long as they take. Specifying 300,000 ++ for this value provides a 5-minute timeout. ++ + smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices + smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port + smsc-ircc2.ircc_sir= [HW] SIR base I/O port +diff --git a/kernel/smp.c b/kernel/smp.c +index 385179dae360e..0a9a3262f7822 100644 +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -168,6 +168,8 @@ static DEFINE_PER_CPU(void *, cur_csd_info); + + static ulong csd_lock_timeout = 5000; /* CSD lock timeout in milliseconds. */ + module_param(csd_lock_timeout, ulong, 0444); ++static int panic_on_ipistall; /* CSD panic timeout in milliseconds, 300000 for five minutes. */ ++module_param(panic_on_ipistall, int, 0444); + + static atomic_t csd_bug_count = ATOMIC_INIT(0); + +@@ -228,6 +230,7 @@ static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 * + } + + ts2 = sched_clock(); ++ /* How long since we last checked for a stuck CSD lock.*/ + ts_delta = ts2 - *ts1; + if (likely(ts_delta <= csd_lock_timeout_ns || csd_lock_timeout_ns == 0)) + return false; +@@ -241,9 +244,17 @@ static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 * + else + cpux = cpu; + cpu_cur_csd = smp_load_acquire(&per_cpu(cur_csd, cpux)); /* Before func and info. */ ++ /* How long since this CSD lock was stuck. */ ++ ts_delta = ts2 - ts0; + pr_alert("csd: %s non-responsive CSD lock (#%d) on CPU#%d, waiting %llu ns for CPU#%02d %pS(%ps).\n", +- firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts2 - ts0, ++ firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts_delta, + cpu, csd->func, csd->info); ++ /* ++ * If the CSD lock is still stuck after 5 minutes, it is unlikely ++ * to become unstuck. Use a signed comparison to avoid triggering ++ * on underflows when the TSC is out of sync between sockets. ++ */ ++ BUG_ON(panic_on_ipistall > 0 && (s64)ts_delta > ((s64)panic_on_ipistall * NSEC_PER_MSEC)); + if (cpu_cur_csd && csd != cpu_cur_csd) { + pr_alert("\tcsd: CSD lock (#%d) handling prior %pS(%ps) request.\n", + *bug_id, READ_ONCE(per_cpu(cur_csd_func, cpux)), +-- +2.42.0 + diff --git a/queue-6.5/soundwire-dmi-quirks-update-hp-omen-match.patch b/queue-6.5/soundwire-dmi-quirks-update-hp-omen-match.patch new file mode 100644 index 00000000000..375e96ff1da --- /dev/null +++ b/queue-6.5/soundwire-dmi-quirks-update-hp-omen-match.patch @@ -0,0 +1,39 @@ +From 39a4150db6a17eb2967fb230d1116776f1a8b7f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 09:08:33 +0800 +Subject: soundwire: dmi-quirks: update HP Omen match + +From: Pierre-Louis Bossart + +[ Upstream commit 4ea2b6d3128ea4d502c4015df0dc16b7d1070954 ] + +New platforms have a slightly different DMI product name, remove +trailing characters/digits to handle all cases + +Closes: https://github.com/thesofproject/linux/issues/4611 +Signed-off-by: Pierre-Louis Bossart +Reviewed-by: Rander Wang +Signed-off-by: Bard Liao +Link: https://lore.kernel.org/r/20231013010833.114271-1-yung-chuan.liao@linux.intel.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/soundwire/dmi-quirks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c +index 2a1096dab63d3..9ebdd0cd0b1cf 100644 +--- a/drivers/soundwire/dmi-quirks.c ++++ b/drivers/soundwire/dmi-quirks.c +@@ -141,7 +141,7 @@ static const struct dmi_system_id adr_remap_quirk_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), +- DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"), + }, + .driver_data = (void *)hp_omen_16, + }, +-- +2.42.0 + diff --git a/queue-6.5/srcu-fix-srcu_struct-node-grpmask-overflow-on-64-bit.patch b/queue-6.5/srcu-fix-srcu_struct-node-grpmask-overflow-on-64-bit.patch new file mode 100644 index 00000000000..ac865920b3c --- /dev/null +++ b/queue-6.5/srcu-fix-srcu_struct-node-grpmask-overflow-on-64-bit.patch @@ -0,0 +1,66 @@ +From 16a8a79eabc87dac290ffcb6f55ad6d60570f7eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 15:21:14 +0300 +Subject: srcu: Fix srcu_struct node grpmask overflow on 64-bit systems + +From: Denis Arefev + +[ Upstream commit d8d5b7bf6f2105883bbd91bbd4d5b67e4e3dff71 ] + +The value of a bitwise expression 1 << (cpu - sdp->mynode->grplo) +is subject to overflow due to a failure to cast operands to a larger +data type before performing the bitwise operation. + +The maximum result of this subtraction is defined by the RCU_FANOUT_LEAF +Kconfig option, which on 64-bit systems defaults to 16 (resulting in a +maximum shift of 15), but which can be set up as high as 64 (resulting +in a maximum shift of 63). A value of 31 can result in sign extension, +resulting in 0xffffffff80000000 instead of the desired 0x80000000. +A value of 32 or greater triggers undefined behavior per the C standard. + +This bug has not been known to cause issues because almost all kernels +take the default CONFIG_RCU_FANOUT_LEAF=16. Furthermore, as long as a +given compiler gives a deterministic non-zero result for 1<=32, +the code correctly invokes all SRCU callbacks, albeit wasting CPU time +along the way. + +This commit therefore substitutes the correct 1UL for the buggy 1. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Denis Arefev +Reviewed-by: Mathieu Desnoyers +Reviewed-by: Joel Fernandes (Google) +Cc: David Laight +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/rcu/srcutree.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c +index c6481032d42be..7522517b63b6f 100644 +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -223,7 +223,7 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags) + snp->grplo = cpu; + snp->grphi = cpu; + } +- sdp->grpmask = 1 << (cpu - sdp->mynode->grplo); ++ sdp->grpmask = 1UL << (cpu - sdp->mynode->grplo); + } + smp_store_release(&ssp->srcu_sup->srcu_size_state, SRCU_SIZE_WAIT_BARRIER); + return true; +@@ -833,7 +833,7 @@ static void srcu_schedule_cbs_snp(struct srcu_struct *ssp, struct srcu_node *snp + int cpu; + + for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { +- if (!(mask & (1 << (cpu - snp->grplo)))) ++ if (!(mask & (1UL << (cpu - snp->grplo)))) + continue; + srcu_schedule_cbs_sdp(per_cpu_ptr(ssp->sda, cpu), delay); + } +-- +2.42.0 + diff --git a/queue-6.5/srcu-only-accelerate-on-enqueue-time.patch b/queue-6.5/srcu-only-accelerate-on-enqueue-time.patch new file mode 100644 index 00000000000..da96aa5d8a9 --- /dev/null +++ b/queue-6.5/srcu-only-accelerate-on-enqueue-time.patch @@ -0,0 +1,68 @@ +From bf242e6bde2d8ecb8675db8f9a008424c3e18097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 01:29:00 +0200 +Subject: srcu: Only accelerate on enqueue time + +From: Frederic Weisbecker + +[ Upstream commit 8a77f38bcd28d3c22ab7dd8eff3f299d43c00411 ] + +Acceleration in SRCU happens on enqueue time for each new callback. This +operation is expected not to fail and therefore any similar attempt +from other places shouldn't find any remaining callbacks to accelerate. + +Moreover accelerations performed beyond enqueue time are error prone +because rcu_seq_snap() then may return the snapshot for a new grace +period that is not going to be started. + +Remove these dangerous and needless accelerations and introduce instead +assertions reporting leaking unaccelerated callbacks beyond enqueue +time. + +Co-developed-by: Yong He +Signed-off-by: Yong He +Co-developed-by: Joel Fernandes (Google) +Signed-off-by: Joel Fernandes (Google) +Co-developed-by: Neeraj upadhyay +Signed-off-by: Neeraj upadhyay +Reviewed-by: Like Xu +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/rcu/srcutree.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c +index 7522517b63b6f..2f770a9a2a13a 100644 +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -782,8 +782,7 @@ static void srcu_gp_start(struct srcu_struct *ssp) + spin_lock_rcu_node(sdp); /* Interrupts already disabled. */ + rcu_segcblist_advance(&sdp->srcu_cblist, + rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq)); +- (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, +- rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq)); ++ WARN_ON_ONCE(!rcu_segcblist_segempty(&sdp->srcu_cblist, RCU_NEXT_TAIL)); + spin_unlock_rcu_node(sdp); /* Interrupts remain disabled. */ + WRITE_ONCE(ssp->srcu_sup->srcu_gp_start, jiffies); + WRITE_ONCE(ssp->srcu_sup->srcu_n_exp_nodelay, 0); +@@ -1719,6 +1718,7 @@ static void srcu_invoke_callbacks(struct work_struct *work) + ssp = sdp->ssp; + rcu_cblist_init(&ready_cbs); + spin_lock_irq_rcu_node(sdp); ++ WARN_ON_ONCE(!rcu_segcblist_segempty(&sdp->srcu_cblist, RCU_NEXT_TAIL)); + rcu_segcblist_advance(&sdp->srcu_cblist, + rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq)); + if (sdp->srcu_cblist_invoking || +@@ -1748,8 +1748,6 @@ static void srcu_invoke_callbacks(struct work_struct *work) + */ + spin_lock_irq_rcu_node(sdp); + rcu_segcblist_add_len(&sdp->srcu_cblist, -len); +- (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, +- rcu_seq_snap(&ssp->srcu_sup->srcu_gp_seq)); + sdp->srcu_cblist_invoking = false; + more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist); + spin_unlock_irq_rcu_node(sdp); +-- +2.42.0 + diff --git a/queue-6.5/string.h-add-array-wrappers-for-v-memdup_user.patch b/queue-6.5/string.h-add-array-wrappers-for-v-memdup_user.patch new file mode 100644 index 00000000000..d1beddd4a56 --- /dev/null +++ b/queue-6.5/string.h-add-array-wrappers-for-v-memdup_user.patch @@ -0,0 +1,94 @@ +From f4c00fe160be009447e08611c31b4591ee9961a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 14:36:09 +0200 +Subject: string.h: add array-wrappers for (v)memdup_user() + +From: Philipp Stanner + +[ Upstream commit 313ebe47d75558511aa1237b6e35c663b5c0ec6f ] + +Currently, user array duplications are sometimes done without an +overflow check. Sometimes the checks are done manually; sometimes the +array size is calculated with array_size() and sometimes by calculating +n * size directly in code. + +Introduce wrappers for arrays for memdup_user() and vmemdup_user() to +provide a standardized and safe way for duplicating user arrays. + +This is both for new code as well as replacing usage of (v)memdup_user() +in existing code that uses, e.g., n * size to calculate array sizes. + +Suggested-by: David Airlie +Signed-off-by: Philipp Stanner +Reviewed-by: Andy Shevchenko +Reviewed-by: Kees Cook +Reviewed-by: Zack Rusin +Signed-off-by: Dave Airlie +Link: https://patchwork.freedesktop.org/patch/msgid/20230920123612.16914-3-pstanner@redhat.com +Signed-off-by: Sasha Levin +--- + include/linux/string.h | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/include/linux/string.h b/include/linux/string.h +index 9e3cb6923b0ef..5077776e995e0 100644 +--- a/include/linux/string.h ++++ b/include/linux/string.h +@@ -5,7 +5,9 @@ + #include /* for inline */ + #include /* for size_t */ + #include /* for NULL */ ++#include /* for ERR_PTR() */ + #include /* for E2BIG */ ++#include /* for check_mul_overflow() */ + #include + #include + +@@ -14,6 +16,44 @@ extern void *memdup_user(const void __user *, size_t); + extern void *vmemdup_user(const void __user *, size_t); + extern void *memdup_user_nul(const void __user *, size_t); + ++/** ++ * memdup_array_user - duplicate array from user space ++ * @src: source address in user space ++ * @n: number of array members to copy ++ * @size: size of one array member ++ * ++ * Return: an ERR_PTR() on failure. Result is physically ++ * contiguous, to be freed by kfree(). ++ */ ++static inline void *memdup_array_user(const void __user *src, size_t n, size_t size) ++{ ++ size_t nbytes; ++ ++ if (check_mul_overflow(n, size, &nbytes)) ++ return ERR_PTR(-EOVERFLOW); ++ ++ return memdup_user(src, nbytes); ++} ++ ++/** ++ * vmemdup_array_user - duplicate array from user space ++ * @src: source address in user space ++ * @n: number of array members to copy ++ * @size: size of one array member ++ * ++ * Return: an ERR_PTR() on failure. Result may be not ++ * physically contiguous. Use kvfree() to free. ++ */ ++static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size) ++{ ++ size_t nbytes; ++ ++ if (check_mul_overflow(n, size, &nbytes)) ++ return ERR_PTR(-EOVERFLOW); ++ ++ return vmemdup_user(src, nbytes); ++} ++ + /* + * Include machine specific inline routines + */ +-- +2.42.0 + diff --git a/queue-6.5/sunrpc-add-an-is_err-check-back-to-where-it-was.patch b/queue-6.5/sunrpc-add-an-is_err-check-back-to-where-it-was.patch new file mode 100644 index 00000000000..e99ca225480 --- /dev/null +++ b/queue-6.5/sunrpc-add-an-is_err-check-back-to-where-it-was.patch @@ -0,0 +1,44 @@ +From ca270042c67136f811c89b6401fca2b30bdaec17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Oct 2023 11:00:22 +0300 +Subject: SUNRPC: Add an IS_ERR() check back to where it was + +From: Dan Carpenter + +[ Upstream commit 4f3ed837186fc0d2722ba8d2457a594322e9c2ef ] + +This IS_ERR() check was deleted during in a cleanup because, at the time, +the rpcb_call_async() function could not return an error pointer. That +changed in commit 25cf32ad5dba ("SUNRPC: Handle allocation failure in +rpc_new_task()") and now it can return an error pointer. Put the check +back. + +A related revert was done in commit 13bd90141804 ("Revert "SUNRPC: +Remove unreachable error condition""). + +Fixes: 037e910b52b0 ("SUNRPC: Remove unreachable error condition in rpcb_getport_async()") +Signed-off-by: Dan Carpenter +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/rpcb_clnt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c +index 5988a5c5ff3f0..102c3818bc54d 100644 +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -769,6 +769,10 @@ void rpcb_getport_async(struct rpc_task *task) + + child = rpcb_call_async(rpcb_clnt, map, proc); + rpc_release_client(rpcb_clnt); ++ if (IS_ERR(child)) { ++ /* rpcb_map_release() has freed the arguments */ ++ return; ++ } + + xprt->stat.bind_count++; + rpc_put_task(child); +-- +2.42.0 + diff --git a/queue-6.5/sunrpc-econnreset-might-require-a-rebind.patch b/queue-6.5/sunrpc-econnreset-might-require-a-rebind.patch new file mode 100644 index 00000000000..6c8a50133de --- /dev/null +++ b/queue-6.5/sunrpc-econnreset-might-require-a-rebind.patch @@ -0,0 +1,43 @@ +From 10f33dd5dd562a6de4dab481312209644a6ec147 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 09:06:05 -0400 +Subject: SUNRPC: ECONNRESET might require a rebind + +From: Trond Myklebust + +[ Upstream commit 4b09ca1508a60be30b2e3940264e93d7aeb5c97e ] + +If connect() is returning ECONNRESET, it usually means that nothing is +listening on that port. If so, a rebind might be required in order to +obtain the new port on which the RPC service is listening. + +Fixes: fd01b2597941 ("SUNRPC: ECONNREFUSED should cause a rebind.") +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/clnt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 9fb0ccabc1a26..2e3b7b2c1b431 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2169,6 +2169,7 @@ call_connect_status(struct rpc_task *task) + task->tk_status = 0; + switch (status) { + case -ECONNREFUSED: ++ case -ECONNRESET: + /* A positive refusal suggests a rebind is needed. */ + if (RPC_IS_SOFTCONN(task)) + break; +@@ -2177,7 +2178,6 @@ call_connect_status(struct rpc_task *task) + goto out_retry; + } + fallthrough; +- case -ECONNRESET: + case -ECONNABORTED: + case -ENETDOWN: + case -ENETUNREACH: +-- +2.42.0 + diff --git a/queue-6.5/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch b/queue-6.5/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch new file mode 100644 index 00000000000..5882d2c4aa2 --- /dev/null +++ b/queue-6.5/sunrpc-fix-rpc-client-cleaned-up-the-freed-pipefs-de.patch @@ -0,0 +1,121 @@ +From 709169b2f484abfd3d8ffb07d13924887677f4f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 09:40:19 +0800 +Subject: SUNRPC: Fix RPC client cleaned up the freed pipefs dentries + +From: felix + +[ Upstream commit bfca5fb4e97c46503ddfc582335917b0cc228264 ] + +RPC client pipefs dentries cleanup is in separated rpc_remove_pipedir() +workqueue,which takes care about pipefs superblock locking. +In some special scenarios, when kernel frees the pipefs sb of the +current client and immediately alloctes a new pipefs sb, +rpc_remove_pipedir function would misjudge the existence of pipefs +sb which is not the one it used to hold. As a result, +the rpc_remove_pipedir would clean the released freed pipefs dentries. + +To fix this issue, rpc_remove_pipedir should check whether the +current pipefs sb is consistent with the original pipefs sb. + +This error can be catched by KASAN: +========================================================= +[ 250.497700] BUG: KASAN: slab-use-after-free in dget_parent+0x195/0x200 +[ 250.498315] Read of size 4 at addr ffff88800a2ab804 by task kworker/0:18/106503 +[ 250.500549] Workqueue: events rpc_free_client_work +[ 250.501001] Call Trace: +[ 250.502880] kasan_report+0xb6/0xf0 +[ 250.503209] ? dget_parent+0x195/0x200 +[ 250.503561] dget_parent+0x195/0x200 +[ 250.503897] ? __pfx_rpc_clntdir_depopulate+0x10/0x10 +[ 250.504384] rpc_rmdir_depopulate+0x1b/0x90 +[ 250.504781] rpc_remove_client_dir+0xf5/0x150 +[ 250.505195] rpc_free_client_work+0xe4/0x230 +[ 250.505598] process_one_work+0x8ee/0x13b0 +... +[ 22.039056] Allocated by task 244: +[ 22.039390] kasan_save_stack+0x22/0x50 +[ 22.039758] kasan_set_track+0x25/0x30 +[ 22.040109] __kasan_slab_alloc+0x59/0x70 +[ 22.040487] kmem_cache_alloc_lru+0xf0/0x240 +[ 22.040889] __d_alloc+0x31/0x8e0 +[ 22.041207] d_alloc+0x44/0x1f0 +[ 22.041514] __rpc_lookup_create_exclusive+0x11c/0x140 +[ 22.041987] rpc_mkdir_populate.constprop.0+0x5f/0x110 +[ 22.042459] rpc_create_client_dir+0x34/0x150 +[ 22.042874] rpc_setup_pipedir_sb+0x102/0x1c0 +[ 22.043284] rpc_client_register+0x136/0x4e0 +[ 22.043689] rpc_new_client+0x911/0x1020 +[ 22.044057] rpc_create_xprt+0xcb/0x370 +[ 22.044417] rpc_create+0x36b/0x6c0 +... +[ 22.049524] Freed by task 0: +[ 22.049803] kasan_save_stack+0x22/0x50 +[ 22.050165] kasan_set_track+0x25/0x30 +[ 22.050520] kasan_save_free_info+0x2b/0x50 +[ 22.050921] __kasan_slab_free+0x10e/0x1a0 +[ 22.051306] kmem_cache_free+0xa5/0x390 +[ 22.051667] rcu_core+0x62c/0x1930 +[ 22.051995] __do_softirq+0x165/0x52a +[ 22.052347] +[ 22.052503] Last potentially related work creation: +[ 22.052952] kasan_save_stack+0x22/0x50 +[ 22.053313] __kasan_record_aux_stack+0x8e/0xa0 +[ 22.053739] __call_rcu_common.constprop.0+0x6b/0x8b0 +[ 22.054209] dentry_free+0xb2/0x140 +[ 22.054540] __dentry_kill+0x3be/0x540 +[ 22.054900] shrink_dentry_list+0x199/0x510 +[ 22.055293] shrink_dcache_parent+0x190/0x240 +[ 22.055703] do_one_tree+0x11/0x40 +[ 22.056028] shrink_dcache_for_umount+0x61/0x140 +[ 22.056461] generic_shutdown_super+0x70/0x590 +[ 22.056879] kill_anon_super+0x3a/0x60 +[ 22.057234] rpc_kill_sb+0x121/0x200 + +Fixes: 0157d021d23a ("SUNRPC: handle RPC client pipefs dentries by network namespace aware routines") +Signed-off-by: felix +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/clnt.h | 1 + + net/sunrpc/clnt.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h +index 4f41d839face4..03722690f2c39 100644 +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -92,6 +92,7 @@ struct rpc_clnt { + }; + const struct cred *cl_cred; + unsigned int cl_max_connect; /* max number of transports not to the same IP */ ++ struct super_block *pipefs_sb; + }; + + /* +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 2e3b7b2c1b431..a148aa8003b88 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -111,7 +111,8 @@ static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) + + pipefs_sb = rpc_get_sb_net(net); + if (pipefs_sb) { +- __rpc_clnt_remove_pipedir(clnt); ++ if (pipefs_sb == clnt->pipefs_sb) ++ __rpc_clnt_remove_pipedir(clnt); + rpc_put_sb_net(net); + } + } +@@ -151,6 +152,8 @@ rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt) + { + struct dentry *dentry; + ++ clnt->pipefs_sb = pipefs_sb; ++ + if (clnt->cl_program->pipe_dir_name != NULL) { + dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt); + if (IS_ERR(dentry)) +-- +2.42.0 + diff --git a/queue-6.5/thunderbolt-apply-usb-3.x-bandwidth-quirk-only-in-so.patch b/queue-6.5/thunderbolt-apply-usb-3.x-bandwidth-quirk-only-in-so.patch new file mode 100644 index 00000000000..712659f5513 --- /dev/null +++ b/queue-6.5/thunderbolt-apply-usb-3.x-bandwidth-quirk-only-in-so.patch @@ -0,0 +1,36 @@ +From f20a92cf0380f5c00545b3a3e5bdb32ca4ed3017 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 10:10:35 +0300 +Subject: thunderbolt: Apply USB 3.x bandwidth quirk only in software + connection manager + +From: Mika Westerberg + +[ Upstream commit 0c35ac18256942e66d8dab6ca049185812e60c69 ] + +This is not needed when firmware connection manager is run so limit this +to software connection manager. + +Signed-off-by: Mika Westerberg +Signed-off-by: Sasha Levin +--- + drivers/thunderbolt/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c +index 488138a28ae13..e6bfa63b40aee 100644 +--- a/drivers/thunderbolt/quirks.c ++++ b/drivers/thunderbolt/quirks.c +@@ -31,6 +31,9 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw) + { + struct tb_port *port; + ++ if (tb_switch_is_icm(sw)) ++ return; ++ + tb_switch_for_each_port(sw, port) { + if (!tb_port_is_usb3_down(port)) + continue; +-- +2.42.0 + diff --git a/queue-6.5/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch b/queue-6.5/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch new file mode 100644 index 00000000000..8d74ad20c7a --- /dev/null +++ b/queue-6.5/tipc-fix-kernel-infoleak-due-to-uninitialized-tlv-va.patch @@ -0,0 +1,113 @@ +From 65cec9e5dbdd06a908c5d17653f9d5b7ef25bcd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 Nov 2023 01:39:47 +0900 +Subject: tipc: Fix kernel-infoleak due to uninitialized TLV value + +From: Shigeru Yoshida + +[ Upstream commit fb317eb23b5ee4c37b0656a9a52a3db58d9dd072 ] + +KMSAN reported the following kernel-infoleak issue: + +===================================================== +BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline] +BUG: KMSAN: kernel-infoleak in copy_to_user_iter lib/iov_iter.c:24 [inline] +BUG: KMSAN: kernel-infoleak in iterate_ubuf include/linux/iov_iter.h:29 [inline] +BUG: KMSAN: kernel-infoleak in iterate_and_advance2 include/linux/iov_iter.h:245 [inline] +BUG: KMSAN: kernel-infoleak in iterate_and_advance include/linux/iov_iter.h:271 [inline] +BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x4ec/0x2bc0 lib/iov_iter.c:186 + instrument_copy_to_user include/linux/instrumented.h:114 [inline] + copy_to_user_iter lib/iov_iter.c:24 [inline] + iterate_ubuf include/linux/iov_iter.h:29 [inline] + iterate_and_advance2 include/linux/iov_iter.h:245 [inline] + iterate_and_advance include/linux/iov_iter.h:271 [inline] + _copy_to_iter+0x4ec/0x2bc0 lib/iov_iter.c:186 + copy_to_iter include/linux/uio.h:197 [inline] + simple_copy_to_iter net/core/datagram.c:532 [inline] + __skb_datagram_iter.5+0x148/0xe30 net/core/datagram.c:420 + skb_copy_datagram_iter+0x52/0x210 net/core/datagram.c:546 + skb_copy_datagram_msg include/linux/skbuff.h:3960 [inline] + netlink_recvmsg+0x43d/0x1630 net/netlink/af_netlink.c:1967 + sock_recvmsg_nosec net/socket.c:1044 [inline] + sock_recvmsg net/socket.c:1066 [inline] + __sys_recvfrom+0x476/0x860 net/socket.c:2246 + __do_sys_recvfrom net/socket.c:2264 [inline] + __se_sys_recvfrom net/socket.c:2260 [inline] + __x64_sys_recvfrom+0x130/0x200 net/socket.c:2260 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Uninit was created at: + slab_post_alloc_hook+0x103/0x9e0 mm/slab.h:768 + slab_alloc_node mm/slub.c:3478 [inline] + kmem_cache_alloc_node+0x5f7/0xb50 mm/slub.c:3523 + kmalloc_reserve+0x13c/0x4a0 net/core/skbuff.c:560 + __alloc_skb+0x2fd/0x770 net/core/skbuff.c:651 + alloc_skb include/linux/skbuff.h:1286 [inline] + tipc_tlv_alloc net/tipc/netlink_compat.c:156 [inline] + tipc_get_err_tlv+0x90/0x5d0 net/tipc/netlink_compat.c:170 + tipc_nl_compat_recv+0x1042/0x15d0 net/tipc/netlink_compat.c:1324 + genl_family_rcv_msg_doit net/netlink/genetlink.c:972 [inline] + genl_family_rcv_msg net/netlink/genetlink.c:1052 [inline] + genl_rcv_msg+0x1220/0x12c0 net/netlink/genetlink.c:1067 + netlink_rcv_skb+0x4a4/0x6a0 net/netlink/af_netlink.c:2545 + genl_rcv+0x41/0x60 net/netlink/genetlink.c:1076 + netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline] + netlink_unicast+0xf4b/0x1230 net/netlink/af_netlink.c:1368 + netlink_sendmsg+0x1242/0x1420 net/netlink/af_netlink.c:1910 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + ____sys_sendmsg+0x997/0xd60 net/socket.c:2588 + ___sys_sendmsg+0x271/0x3b0 net/socket.c:2642 + __sys_sendmsg net/socket.c:2671 [inline] + __do_sys_sendmsg net/socket.c:2680 [inline] + __se_sys_sendmsg net/socket.c:2678 [inline] + __x64_sys_sendmsg+0x2fa/0x4a0 net/socket.c:2678 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Bytes 34-35 of 36 are uninitialized +Memory access of size 36 starts at ffff88802d464a00 +Data copied to user address 00007ff55033c0a0 + +CPU: 0 PID: 30322 Comm: syz-executor.0 Not tainted 6.6.0-14500-g1c41041124bd #10 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc38 04/01/2014 +===================================================== + +tipc_add_tlv() puts TLV descriptor and value onto `skb`. This size is +calculated with TLV_SPACE() macro. It adds the size of struct tlv_desc and +the length of TLV value passed as an argument, and aligns the result to a +multiple of TLV_ALIGNTO, i.e., a multiple of 4 bytes. + +If the size of struct tlv_desc plus the length of TLV value is not aligned, +the current implementation leaves the remaining bytes uninitialized. This +is the cause of the above kernel-infoleak issue. + +This patch resolves this issue by clearing data up to an aligned size. + +Fixes: d0796d1ef63d ("tipc: convert legacy nl bearer dump to nl compat") +Signed-off-by: Shigeru Yoshida +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/tipc/netlink_compat.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c +index 9b47c84092319..42d9586365ae3 100644 +--- a/net/tipc/netlink_compat.c ++++ b/net/tipc/netlink_compat.c +@@ -102,6 +102,7 @@ static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) + return -EMSGSIZE; + + skb_put(skb, TLV_SPACE(len)); ++ memset(tlv, 0, TLV_SPACE(len)); + tlv->tlv_type = htons(type); + tlv->tlv_len = htons(TLV_LENGTH(len)); + if (len && data) +-- +2.42.0 + diff --git a/queue-6.5/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch b/queue-6.5/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch new file mode 100644 index 00000000000..a3df3e14aa6 --- /dev/null +++ b/queue-6.5/tools-power-turbostat-enable-the-c-state-pre-wake-pr.patch @@ -0,0 +1,36 @@ +From b03287a3d7a462c3b6a7b5ed524270c35502b27b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Mar 2023 11:17:44 +0800 +Subject: tools/power/turbostat: Enable the C-state Pre-wake printing + +From: Chen Yu + +[ Upstream commit b61b7d8c4c22c4298a50ae5d0ee88facb85ce665 ] + +Currently the C-state Pre-wake will not be printed due to the +probe has not been invoked. Invoke the probe function accordingly. + +Fixes: aeb01e6d71ff ("tools/power turbostat: Print the C-state Pre-wake settings") +Signed-off-by: Chen Yu +Reviewed-by: Zhang Rui +Reviewed-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index a938699ca2419..ce9860e388bd4 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -5790,6 +5790,7 @@ void process_cpuid() + rapl_probe(family, model); + perf_limit_reasons_probe(family, model); + automatic_cstate_conversion_probe(family, model); ++ prewake_cstate_probe(family, model); + + check_tcc_offset(model_orig); + +-- +2.42.0 + diff --git a/queue-6.5/tools-power-turbostat-fix-a-knl-bug.patch b/queue-6.5/tools-power-turbostat-fix-a-knl-bug.patch new file mode 100644 index 00000000000..b26e68738e5 --- /dev/null +++ b/queue-6.5/tools-power-turbostat-fix-a-knl-bug.patch @@ -0,0 +1,41 @@ +From 727cafc7022c1bb0a9971d17c2db1a7f812934d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Mar 2023 21:57:07 +0800 +Subject: tools/power/turbostat: Fix a knl bug + +From: Zhang Rui + +[ Upstream commit 137f01b3529d292a68d22e9681e2f903c768f790 ] + +MSR_KNL_CORE_C6_RESIDENCY should be evaluated only if +1. this is KNL platform +AND +2. need to get C6 residency or need to calculate C1 residency + +Fix the broken logic introduced by commit 1e9042b9c8d4 ("tools/power +turbostat: Fix CPU%C1 display value"). + +Fixes: 1e9042b9c8d4 ("tools/power turbostat: Fix CPU%C1 display value") +Signed-off-by: Zhang Rui +Reviewed-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 8a36ba5df9f90..a938699ca2419 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -2180,7 +2180,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) + if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) { + if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) + return -7; +- } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) { ++ } else if (do_knl_cstates && soft_c1_residency_display(BIC_CPU_c6)) { + if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) + return -7; + } +-- +2.42.0 + diff --git a/queue-6.5/tsnep-fix-tsnep_request_irq-format-overflow-warning.patch b/queue-6.5/tsnep-fix-tsnep_request_irq-format-overflow-warning.patch new file mode 100644 index 00000000000..8cd548668f1 --- /dev/null +++ b/queue-6.5/tsnep-fix-tsnep_request_irq-format-overflow-warning.patch @@ -0,0 +1,80 @@ +From d1054ab4c5dfe3cd7285afa2dad43d2f5c75d307 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Oct 2023 20:38:56 +0200 +Subject: tsnep: Fix tsnep_request_irq() format-overflow warning + +From: Gerhard Engleder + +[ Upstream commit 00e984cb986b31e9313745e51daceaa1e1eb7351 ] + +Compiler warns about a possible format-overflow in tsnep_request_irq(): +drivers/net/ethernet/engleder/tsnep_main.c:884:55: warning: 'sprintf' may write a terminating nul past the end of the destination [-Wformat-overflow=] + sprintf(queue->name, "%s-rx-%d", name, + ^ +drivers/net/ethernet/engleder/tsnep_main.c:881:55: warning: 'sprintf' may write a terminating nul past the end of the destination [-Wformat-overflow=] + sprintf(queue->name, "%s-tx-%d", name, + ^ +drivers/net/ethernet/engleder/tsnep_main.c:878:49: warning: '-txrx-' directive writing 6 bytes into a region of size between 5 and 25 [-Wformat-overflow=] + sprintf(queue->name, "%s-txrx-%d", name, + ^~~~~~ + +Actually overflow cannot happen. Name is limited to IFNAMSIZ, because +netdev_name() is called during ndo_open(). queue_index is single char, +because less than 10 queues are supported. + +Fix warning with snprintf(). Additionally increase buffer to 32 bytes, +because those 7 additional bytes were unused anyway. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202310182028.vmDthIUa-lkp@intel.com/ +Signed-off-by: Gerhard Engleder +Reviewed-by: Jacob Keller +Link: https://lore.kernel.org/r/20231023183856.58373-1-gerhard@engleder-embedded.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/engleder/tsnep.h | 2 +- + drivers/net/ethernet/engleder/tsnep_main.c | 12 ++++++------ + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/engleder/tsnep.h b/drivers/net/ethernet/engleder/tsnep.h +index 11b29f56aaf9c..b91abe9efb517 100644 +--- a/drivers/net/ethernet/engleder/tsnep.h ++++ b/drivers/net/ethernet/engleder/tsnep.h +@@ -142,7 +142,7 @@ struct tsnep_rx { + + struct tsnep_queue { + struct tsnep_adapter *adapter; +- char name[IFNAMSIZ + 9]; ++ char name[IFNAMSIZ + 16]; + + struct tsnep_tx *tx; + struct tsnep_rx *rx; +diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c +index 479156576bc8a..e3fc894fa3f6f 100644 +--- a/drivers/net/ethernet/engleder/tsnep_main.c ++++ b/drivers/net/ethernet/engleder/tsnep_main.c +@@ -1778,14 +1778,14 @@ static int tsnep_request_irq(struct tsnep_queue *queue, bool first) + dev = queue->adapter; + } else { + if (queue->tx && queue->rx) +- sprintf(queue->name, "%s-txrx-%d", name, +- queue->rx->queue_index); ++ snprintf(queue->name, sizeof(queue->name), "%s-txrx-%d", ++ name, queue->rx->queue_index); + else if (queue->tx) +- sprintf(queue->name, "%s-tx-%d", name, +- queue->tx->queue_index); ++ snprintf(queue->name, sizeof(queue->name), "%s-tx-%d", ++ name, queue->tx->queue_index); + else +- sprintf(queue->name, "%s-rx-%d", name, +- queue->rx->queue_index); ++ snprintf(queue->name, sizeof(queue->name), "%s-rx-%d", ++ name, queue->rx->queue_index); + handler = tsnep_irq_txrx; + dev = queue; + } +-- +2.42.0 + diff --git a/queue-6.5/tty-fix-uninit-value-access-in-ppp_sync_receive.patch b/queue-6.5/tty-fix-uninit-value-access-in-ppp_sync_receive.patch new file mode 100644 index 00000000000..928fab4bbd2 --- /dev/null +++ b/queue-6.5/tty-fix-uninit-value-access-in-ppp_sync_receive.patch @@ -0,0 +1,82 @@ +From 48efb548b6c7d6c9718e9d99a8caa83c4ace452d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Nov 2023 00:44:20 +0900 +Subject: tty: Fix uninit-value access in ppp_sync_receive() + +From: Shigeru Yoshida + +[ Upstream commit 719639853d88071dfdfd8d9971eca9c283ff314c ] + +KMSAN reported the following uninit-value access issue: + +===================================================== +BUG: KMSAN: uninit-value in ppp_sync_input drivers/net/ppp/ppp_synctty.c:690 [inline] +BUG: KMSAN: uninit-value in ppp_sync_receive+0xdc9/0xe70 drivers/net/ppp/ppp_synctty.c:334 + ppp_sync_input drivers/net/ppp/ppp_synctty.c:690 [inline] + ppp_sync_receive+0xdc9/0xe70 drivers/net/ppp/ppp_synctty.c:334 + tiocsti+0x328/0x450 drivers/tty/tty_io.c:2295 + tty_ioctl+0x808/0x1920 drivers/tty/tty_io.c:2694 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:871 [inline] + __se_sys_ioctl+0x211/0x400 fs/ioctl.c:857 + __x64_sys_ioctl+0x97/0xe0 fs/ioctl.c:857 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Uninit was created at: + __alloc_pages+0x75d/0xe80 mm/page_alloc.c:4591 + __alloc_pages_node include/linux/gfp.h:238 [inline] + alloc_pages_node include/linux/gfp.h:261 [inline] + __page_frag_cache_refill+0x9a/0x2c0 mm/page_alloc.c:4691 + page_frag_alloc_align+0x91/0x5d0 mm/page_alloc.c:4722 + page_frag_alloc include/linux/gfp.h:322 [inline] + __netdev_alloc_skb+0x215/0x6d0 net/core/skbuff.c:728 + netdev_alloc_skb include/linux/skbuff.h:3225 [inline] + dev_alloc_skb include/linux/skbuff.h:3238 [inline] + ppp_sync_input drivers/net/ppp/ppp_synctty.c:669 [inline] + ppp_sync_receive+0x237/0xe70 drivers/net/ppp/ppp_synctty.c:334 + tiocsti+0x328/0x450 drivers/tty/tty_io.c:2295 + tty_ioctl+0x808/0x1920 drivers/tty/tty_io.c:2694 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:871 [inline] + __se_sys_ioctl+0x211/0x400 fs/ioctl.c:857 + __x64_sys_ioctl+0x97/0xe0 fs/ioctl.c:857 + do_syscall_x64 arch/x86/entry/common.c:51 [inline] + do_syscall_64+0x44/0x110 arch/x86/entry/common.c:82 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +CPU: 0 PID: 12950 Comm: syz-executor.1 Not tainted 6.6.0-14500-g1c41041124bd #10 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc38 04/01/2014 +===================================================== + +ppp_sync_input() checks the first 2 bytes of the data are PPP_ALLSTATIONS +and PPP_UI. However, if the data length is 1 and the first byte is +PPP_ALLSTATIONS, an access to an uninitialized value occurs when checking +PPP_UI. This patch resolves this issue by checking the data length. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Shigeru Yoshida +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ppp/ppp_synctty.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c +index 18283b7b94bcd..1ac231408398a 100644 +--- a/drivers/net/ppp/ppp_synctty.c ++++ b/drivers/net/ppp/ppp_synctty.c +@@ -697,7 +697,7 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf, + + /* strip address/control field if present */ + p = skb->data; +- if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { ++ if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + /* chop off address/control */ + if (skb->len < 3) + goto err; +-- +2.42.0 + diff --git a/queue-6.5/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch b/queue-6.5/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch new file mode 100644 index 00000000000..222daf1c9cd --- /dev/null +++ b/queue-6.5/tty-vcc-add-check-for-kstrdup-in-vcc_probe.patch @@ -0,0 +1,76 @@ +From 42d0532e7c9d7c5fea493ba2db2c2712d66faec1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 11:52:20 +0800 +Subject: tty: vcc: Add check for kstrdup() in vcc_probe() + +From: Yi Yang + +[ Upstream commit d81ffb87aaa75f842cd7aa57091810353755b3e6 ] + +Add check for the return value of kstrdup() and return the error, if it +fails in order to avoid NULL pointer dereference. + +Signed-off-by: Yi Yang +Reviewed-by: Jiri Slaby +Link: https://lore.kernel.org/r/20230904035220.48164-1-yiyang13@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/vcc.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c +index 34ba6e54789a7..b8b832c75b856 100644 +--- a/drivers/tty/vcc.c ++++ b/drivers/tty/vcc.c +@@ -579,18 +579,22 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) + return -ENOMEM; + + name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); ++ if (!name) { ++ rv = -ENOMEM; ++ goto free_port; ++ } + + rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, + ARRAY_SIZE(vcc_versions), NULL, name); + if (rv) +- goto free_port; ++ goto free_name; + + port->vio.debug = vcc_dbg_vio; + vcc_ldc_cfg.debug = vcc_dbg_ldc; + + rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); + if (rv) +- goto free_port; ++ goto free_name; + + spin_lock_init(&port->lock); + +@@ -624,6 +628,11 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) + goto unreg_tty; + } + port->domain = kstrdup(domain, GFP_KERNEL); ++ if (!port->domain) { ++ rv = -ENOMEM; ++ goto unreg_tty; ++ } ++ + + mdesc_release(hp); + +@@ -653,8 +662,9 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) + vcc_table_remove(port->index); + free_ldc: + vio_ldc_free(&port->vio); +-free_port: ++free_name: + kfree(name); ++free_port: + kfree(port); + + return rv; +-- +2.42.0 + diff --git a/queue-6.5/usb-dwc3-core-configure-tx-rx-threshold-for-dwc3_ip.patch b/queue-6.5/usb-dwc3-core-configure-tx-rx-threshold-for-dwc3_ip.patch new file mode 100644 index 00000000000..d14a2952cec --- /dev/null +++ b/queue-6.5/usb-dwc3-core-configure-tx-rx-threshold-for-dwc3_ip.patch @@ -0,0 +1,268 @@ +From f2f1b1a257b8c27624bf6b38b1349ec39b607132 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 12:19:02 +0800 +Subject: usb: dwc3: core: configure TX/RX threshold for DWC3_IP + +From: Stanley Chang + +[ Upstream commit e72fc8d6a12af7ae8dd1b52cf68ed68569d29f80 ] + +In Synopsys's dwc3 data book: +To avoid underrun and overrun during the burst, in a high-latency bus +system (like USB), threshold and burst size control is provided through +GTXTHRCFG and GRXTHRCFG registers. + +In Realtek DHC SoC, DWC3 USB 3.0 uses AHB system bus. When dwc3 is +connected with USB 2.5G Ethernet, there will be overrun problem. +Therefore, setting TX/RX thresholds can avoid this issue. + +Signed-off-by: Stanley Chang +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20230912041904.30721-1-stanley_chang@realtek.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/core.c | 160 +++++++++++++++++++++++++++++++--------- + drivers/usb/dwc3/core.h | 13 ++++ + 2 files changed, 137 insertions(+), 36 deletions(-) + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 343d2570189ff..d25490965b27f 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1094,6 +1094,111 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc) + } + } + ++static void dwc3_config_threshold(struct dwc3 *dwc) ++{ ++ u32 reg; ++ u8 rx_thr_num; ++ u8 rx_maxburst; ++ u8 tx_thr_num; ++ u8 tx_maxburst; ++ ++ /* ++ * Must config both number of packets and max burst settings to enable ++ * RX and/or TX threshold. ++ */ ++ if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { ++ rx_thr_num = dwc->rx_thr_num_pkt_prd; ++ rx_maxburst = dwc->rx_max_burst_prd; ++ tx_thr_num = dwc->tx_thr_num_pkt_prd; ++ tx_maxburst = dwc->tx_max_burst_prd; ++ ++ if (rx_thr_num && rx_maxburst) { ++ reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); ++ reg |= DWC31_RXTHRNUMPKTSEL_PRD; ++ ++ reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); ++ reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num); ++ ++ reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); ++ reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); ++ ++ dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); ++ } ++ ++ if (tx_thr_num && tx_maxburst) { ++ reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); ++ reg |= DWC31_TXTHRNUMPKTSEL_PRD; ++ ++ reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); ++ reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num); ++ ++ reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); ++ reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); ++ ++ dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); ++ } ++ } ++ ++ rx_thr_num = dwc->rx_thr_num_pkt; ++ rx_maxburst = dwc->rx_max_burst; ++ tx_thr_num = dwc->tx_thr_num_pkt; ++ tx_maxburst = dwc->tx_max_burst; ++ ++ if (DWC3_IP_IS(DWC3)) { ++ if (rx_thr_num && rx_maxburst) { ++ reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); ++ reg |= DWC3_GRXTHRCFG_PKTCNTSEL; ++ ++ reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0); ++ reg |= DWC3_GRXTHRCFG_RXPKTCNT(rx_thr_num); ++ ++ reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0); ++ reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); ++ ++ dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); ++ } ++ ++ if (tx_thr_num && tx_maxburst) { ++ reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); ++ reg |= DWC3_GTXTHRCFG_PKTCNTSEL; ++ ++ reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0); ++ reg |= DWC3_GTXTHRCFG_TXPKTCNT(tx_thr_num); ++ ++ reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0); ++ reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); ++ ++ dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); ++ } ++ } else { ++ if (rx_thr_num && rx_maxburst) { ++ reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); ++ reg |= DWC31_GRXTHRCFG_PKTCNTSEL; ++ ++ reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0); ++ reg |= DWC31_GRXTHRCFG_RXPKTCNT(rx_thr_num); ++ ++ reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0); ++ reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); ++ ++ dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); ++ } ++ ++ if (tx_thr_num && tx_maxburst) { ++ reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); ++ reg |= DWC31_GTXTHRCFG_PKTCNTSEL; ++ ++ reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0); ++ reg |= DWC31_GTXTHRCFG_TXPKTCNT(tx_thr_num); ++ ++ reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0); ++ reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); ++ ++ dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); ++ } ++ } ++} ++ + /** + * dwc3_core_init - Low-level initialization of DWC3 Core + * @dwc: Pointer to our controller context structure +@@ -1246,42 +1351,7 @@ static int dwc3_core_init(struct dwc3 *dwc) + dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + } + +- /* +- * Must config both number of packets and max burst settings to enable +- * RX and/or TX threshold. +- */ +- if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { +- u8 rx_thr_num = dwc->rx_thr_num_pkt_prd; +- u8 rx_maxburst = dwc->rx_max_burst_prd; +- u8 tx_thr_num = dwc->tx_thr_num_pkt_prd; +- u8 tx_maxburst = dwc->tx_max_burst_prd; +- +- if (rx_thr_num && rx_maxburst) { +- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); +- reg |= DWC31_RXTHRNUMPKTSEL_PRD; +- +- reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); +- reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num); +- +- reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); +- reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); +- +- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); +- } +- +- if (tx_thr_num && tx_maxburst) { +- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); +- reg |= DWC31_TXTHRNUMPKTSEL_PRD; +- +- reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); +- reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num); +- +- reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); +- reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); +- +- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); +- } +- } ++ dwc3_config_threshold(dwc); + + return 0; + +@@ -1417,6 +1487,10 @@ static void dwc3_get_properties(struct dwc3 *dwc) + u8 lpm_nyet_threshold; + u8 tx_de_emphasis; + u8 hird_threshold; ++ u8 rx_thr_num_pkt = 0; ++ u8 rx_max_burst = 0; ++ u8 tx_thr_num_pkt = 0; ++ u8 tx_max_burst = 0; + u8 rx_thr_num_pkt_prd = 0; + u8 rx_max_burst_prd = 0; + u8 tx_thr_num_pkt_prd = 0; +@@ -1479,6 +1553,14 @@ static void dwc3_get_properties(struct dwc3 *dwc) + "snps,usb2-lpm-disable"); + dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev, + "snps,usb2-gadget-lpm-disable"); ++ device_property_read_u8(dev, "snps,rx-thr-num-pkt", ++ &rx_thr_num_pkt); ++ device_property_read_u8(dev, "snps,rx-max-burst", ++ &rx_max_burst); ++ device_property_read_u8(dev, "snps,tx-thr-num-pkt", ++ &tx_thr_num_pkt); ++ device_property_read_u8(dev, "snps,tx-max-burst", ++ &tx_max_burst); + device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", + &rx_thr_num_pkt_prd); + device_property_read_u8(dev, "snps,rx-max-burst-prd", +@@ -1560,6 +1642,12 @@ static void dwc3_get_properties(struct dwc3 *dwc) + + dwc->hird_threshold = hird_threshold; + ++ dwc->rx_thr_num_pkt = rx_thr_num_pkt; ++ dwc->rx_max_burst = rx_max_burst; ++ ++ dwc->tx_thr_num_pkt = tx_thr_num_pkt; ++ dwc->tx_max_burst = tx_max_burst; ++ + dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd; + dwc->rx_max_burst_prd = rx_max_burst_prd; + +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index a69ac67d89fe6..6782ec8bfd64c 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -211,6 +211,11 @@ + #define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24) + #define DWC3_GRXTHRCFG_PKTCNTSEL BIT(29) + ++/* Global TX Threshold Configuration Register */ ++#define DWC3_GTXTHRCFG_MAXTXBURSTSIZE(n) (((n) & 0xff) << 16) ++#define DWC3_GTXTHRCFG_TXPKTCNT(n) (((n) & 0xf) << 24) ++#define DWC3_GTXTHRCFG_PKTCNTSEL BIT(29) ++ + /* Global RX Threshold Configuration Register for DWC_usb31 only */ + #define DWC31_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 16) + #define DWC31_GRXTHRCFG_RXPKTCNT(n) (((n) & 0x1f) << 21) +@@ -1045,6 +1050,10 @@ struct dwc3_scratchpad_array { + * @test_mode_nr: test feature selector + * @lpm_nyet_threshold: LPM NYET response threshold + * @hird_threshold: HIRD threshold ++ * @rx_thr_num_pkt: USB receive packet count ++ * @rx_max_burst: max USB receive burst size ++ * @tx_thr_num_pkt: USB transmit packet count ++ * @tx_max_burst: max USB transmit burst size + * @rx_thr_num_pkt_prd: periodic ESS receive packet count + * @rx_max_burst_prd: max periodic ESS receive burst size + * @tx_thr_num_pkt_prd: periodic ESS transmit packet count +@@ -1273,6 +1282,10 @@ struct dwc3 { + u8 test_mode_nr; + u8 lpm_nyet_threshold; + u8 hird_threshold; ++ u8 rx_thr_num_pkt; ++ u8 rx_max_burst; ++ u8 tx_thr_num_pkt; ++ u8 tx_max_burst; + u8 rx_thr_num_pkt_prd; + u8 rx_max_burst_prd; + u8 tx_thr_num_pkt_prd; +-- +2.42.0 + diff --git a/queue-6.5/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch b/queue-6.5/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch new file mode 100644 index 00000000000..e3d11804d24 --- /dev/null +++ b/queue-6.5/usb-gadget-f_ncm-always-set-current-gadget-in-ncm_bi.patch @@ -0,0 +1,137 @@ +From fc68371e632b1b1380c7da1ffb857f555228ed27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Oct 2023 17:33:24 +0200 +Subject: usb: gadget: f_ncm: Always set current gadget in ncm_bind() + +From: Hardik Gajjar + +[ Upstream commit a04224da1f3424b2c607b12a3bd1f0e302fb8231 ] + +Previously, gadget assignment to the net device occurred exclusively +during the initial binding attempt. + +Nevertheless, the gadget pointer could change during bind/unbind +cycles due to various conditions, including the unloading/loading +of the UDC device driver or the detachment/reconnection of an +OTG-capable USB hub device. + +This patch relocates the gether_set_gadget() function out from +ncm_opts->bound condition check, ensuring that the correct gadget +is assigned during each bind request. + +The provided logs demonstrate the consistency of ncm_opts throughout +the power cycle, while the gadget may change. + +* OTG hub connected during boot up and assignment of gadget and + ncm_opts pointer + +[ 2.366301] usb 2-1.5: New USB device found, idVendor=2996, idProduct=0105 +[ 2.366304] usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 2.366306] usb 2-1.5: Product: H2H Bridge +[ 2.366308] usb 2-1.5: Manufacturer: Aptiv +[ 2.366309] usb 2-1.5: SerialNumber: 13FEB2021 +[ 2.427989] usb 2-1.5: New USB device found, VID=2996, PID=0105 +[ 2.428959] dabridge 2-1.5:1.0: dabridge 2-4 total endpoints=5, 0000000093a8d681 +[ 2.429710] dabridge 2-1.5:1.0: P(0105) D(22.06.22) F(17.3.16) H(1.1) high-speed +[ 2.429714] dabridge 2-1.5:1.0: Hub 2-2 P(0151) V(06.87) +[ 2.429956] dabridge 2-1.5:1.0: All downstream ports in host mode + +[ 2.430093] gadget 000000003c414d59 ------> gadget pointer + +* NCM opts and associated gadget pointer during First ncm_bind + +[ 34.763929] NCM opts 00000000aa304ac9 +[ 34.763930] NCM gadget 000000003c414d59 + +* OTG capable hub disconnecte or assume driver unload. + +[ 97.203114] usb 2-1: USB disconnect, device number 2 +[ 97.203118] usb 2-1.1: USB disconnect, device number 3 +[ 97.209217] usb 2-1.5: USB disconnect, device number 4 +[ 97.230990] dabr_udc deleted + +* Reconnect the OTG hub or load driver assaign new gadget pointer. + +[ 111.534035] usb 2-1.1: New USB device found, idVendor=2996, idProduct=0120, bcdDevice= 6.87 +[ 111.534038] usb 2-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 111.534040] usb 2-1.1: Product: Vendor +[ 111.534041] usb 2-1.1: Manufacturer: Aptiv +[ 111.534042] usb 2-1.1: SerialNumber: Superior +[ 111.535175] usb 2-1.1: New USB device found, VID=2996, PID=0120 +[ 111.610995] usb 2-1.5: new high-speed USB device number 8 using xhci-hcd +[ 111.630052] usb 2-1.5: New USB device found, idVendor=2996, idProduct=0105, bcdDevice=21.02 +[ 111.630055] usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 111.630057] usb 2-1.5: Product: H2H Bridge +[ 111.630058] usb 2-1.5: Manufacturer: Aptiv +[ 111.630059] usb 2-1.5: SerialNumber: 13FEB2021 +[ 111.687464] usb 2-1.5: New USB device found, VID=2996, PID=0105 +[ 111.690375] dabridge 2-1.5:1.0: dabridge 2-8 total endpoints=5, 000000000d87c961 +[ 111.691172] dabridge 2-1.5:1.0: P(0105) D(22.06.22) F(17.3.16) H(1.1) high-speed +[ 111.691176] dabridge 2-1.5:1.0: Hub 2-6 P(0151) V(06.87) +[ 111.691646] dabridge 2-1.5:1.0: All downstream ports in host mode + +[ 111.692298] gadget 00000000dc72f7a9 --------> new gadget ptr on connect + +* NCM opts and associated gadget pointer during second ncm_bind + +[ 113.271786] NCM opts 00000000aa304ac9 -----> same opts ptr used during first bind +[ 113.271788] NCM gadget 00000000dc72f7a9 ----> however new gaget ptr, that will not set + in net_device due to ncm_opts->bound = true + +Signed-off-by: Hardik Gajjar +Link: https://lore.kernel.org/r/20231020153324.82794-1-hgajjar@de.adit-jv.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/function/f_ncm.c | 27 +++++++++++---------------- + 1 file changed, 11 insertions(+), 16 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c +index faf90a2174194..bbb6ff6b11aa1 100644 +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -1425,7 +1425,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) + struct usb_composite_dev *cdev = c->cdev; + struct f_ncm *ncm = func_to_ncm(f); + struct usb_string *us; +- int status; ++ int status = 0; + struct usb_ep *ep; + struct f_ncm_opts *ncm_opts; + +@@ -1443,22 +1443,17 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) + f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; + } + +- /* +- * in drivers/usb/gadget/configfs.c:configfs_composite_bind() +- * configurations are bound in sequence with list_for_each_entry, +- * in each configuration its functions are bound in sequence +- * with list_for_each_entry, so we assume no race condition +- * with regard to ncm_opts->bound access +- */ +- if (!ncm_opts->bound) { +- mutex_lock(&ncm_opts->lock); +- gether_set_gadget(ncm_opts->net, cdev->gadget); ++ mutex_lock(&ncm_opts->lock); ++ gether_set_gadget(ncm_opts->net, cdev->gadget); ++ if (!ncm_opts->bound) + status = gether_register_netdev(ncm_opts->net); +- mutex_unlock(&ncm_opts->lock); +- if (status) +- goto fail; +- ncm_opts->bound = true; +- } ++ mutex_unlock(&ncm_opts->lock); ++ ++ if (status) ++ goto fail; ++ ++ ncm_opts->bound = true; ++ + us = usb_gstrings_attach(cdev, ncm_strings, + ARRAY_SIZE(ncm_string_defs)); + if (IS_ERR(us)) { +-- +2.42.0 + diff --git a/queue-6.5/usb-host-xhci-avoid-xhci-resume-delay-if-ssusb-devic.patch b/queue-6.5/usb-host-xhci-avoid-xhci-resume-delay-if-ssusb-devic.patch new file mode 100644 index 00000000000..478bed075eb --- /dev/null +++ b/queue-6.5/usb-host-xhci-avoid-xhci-resume-delay-if-ssusb-devic.patch @@ -0,0 +1,72 @@ +From 27ae33818f227fdc53a57d0db24aa0e5602e4cc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Oct 2023 13:29:24 +0300 +Subject: usb: host: xhci: Avoid XHCI resume delay if SSUSB device is not + present + +From: Wesley Cheng + +[ Upstream commit 6add6dd345cb754ce18ff992c7264cabf31e59f6 ] + +There is a 120ms delay implemented for allowing the XHCI host controller to +detect a U3 wakeup pulse. The intention is to wait for the device to retry +the wakeup event if the USB3 PORTSC doesn't reflect the RESUME link status +by the time it is checked. As per the USB3 specification: + + tU3WakeupRetryDelay ("Table 7-12. LTSSM State Transition Timeouts") + +This would allow the XHCI resume sequence to determine if the root hub +needs to be also resumed. However, in case there is no device connected, +or if there is only a HSUSB device connected, this delay would still affect +the overall resume timing. + +Since this delay is solely for detecting U3 wake events (USB3 specific) +then ignore this delay for the disconnected case and the HSUSB connected +only case. + +[skip helper function, rename usb3_connected variable -Mathias ] + +Signed-off-by: Wesley Cheng +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20231019102924.2797346-20-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index fae994f679d45..82aab2f9adbb8 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -968,6 +968,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg) + int retval = 0; + bool comp_timer_running = false; + bool pending_portevent = false; ++ bool suspended_usb3_devs = false; + bool reinit_xhc = false; + + if (!hcd->state) +@@ -1115,10 +1116,17 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg) + /* + * Resume roothubs only if there are pending events. + * USB 3 devices resend U3 LFPS wake after a 100ms delay if +- * the first wake signalling failed, give it that chance. ++ * the first wake signalling failed, give it that chance if ++ * there are suspended USB 3 devices. + */ ++ if (xhci->usb3_rhub.bus_state.suspended_ports || ++ xhci->usb3_rhub.bus_state.bus_suspended) ++ suspended_usb3_devs = true; ++ + pending_portevent = xhci_pending_portevent(xhci); +- if (!pending_portevent && msg.event == PM_EVENT_AUTO_RESUME) { ++ ++ if (suspended_usb3_devs && !pending_portevent && ++ msg.event == PM_EVENT_AUTO_RESUME) { + msleep(120); + pending_portevent = xhci_pending_portevent(xhci); + } +-- +2.42.0 + diff --git a/queue-6.5/usb-ucsi-glink-use-the-connector-orientation-gpio-to.patch b/queue-6.5/usb-ucsi-glink-use-the-connector-orientation-gpio-to.patch new file mode 100644 index 00000000000..ee724fd0882 --- /dev/null +++ b/queue-6.5/usb-ucsi-glink-use-the-connector-orientation-gpio-to.patch @@ -0,0 +1,130 @@ +From c33d251fa91046b0ba598400a5d9e711d01ff977 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 12:20:22 +0200 +Subject: usb: ucsi: glink: use the connector orientation GPIO to provide + switch events + +From: Neil Armstrong + +[ Upstream commit c6165ed2f425c273244191930a47c8be23bc51bd ] + +On SM8550, the non-altmode orientation is not given anymore within +altmode events, even with USB SVIDs events. + +On the other side, the Type-C connector orientation is correctly +reported by a signal from the PMIC. + +Take this gpio signal when we detect some Type-C port activity +to notify any Type-C switches tied to the Type-C port connectors. + +Acked-by: Heikki Krogerus +Signed-off-by: Neil Armstrong +Reviewed-by: Dmitry Baryshkov +Acked-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20231002-topic-sm8550-upstream-type-c-orientation-v2-2-125410d3ff95@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi_glink.c | 54 ++++++++++++++++++++++++++++- + 1 file changed, 53 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index 1fe9cb5b6bd96..a2d862eebcecb 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -9,9 +9,13 @@ + #include + #include + #include ++#include ++#include + #include + #include "ucsi.h" + ++#define PMIC_GLINK_MAX_PORTS 2 ++ + #define UCSI_BUF_SIZE 48 + + #define MSG_TYPE_REQ_RESP 1 +@@ -53,6 +57,9 @@ struct ucsi_notify_ind_msg { + struct pmic_glink_ucsi { + struct device *dev; + ++ struct gpio_desc *port_orientation[PMIC_GLINK_MAX_PORTS]; ++ struct typec_switch *port_switch[PMIC_GLINK_MAX_PORTS]; ++ + struct pmic_glink_client *client; + + struct ucsi *ucsi; +@@ -221,8 +228,20 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) + } + + con_num = UCSI_CCI_CONNECTOR(cci); +- if (con_num) ++ if (con_num) { ++ if (con_num < PMIC_GLINK_MAX_PORTS && ++ ucsi->port_orientation[con_num - 1]) { ++ int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]); ++ ++ if (orientation >= 0) { ++ typec_switch_set(ucsi->port_switch[con_num - 1], ++ orientation ? TYPEC_ORIENTATION_REVERSE ++ : TYPEC_ORIENTATION_NORMAL); ++ } ++ } ++ + ucsi_connector_change(ucsi->ucsi, con_num); ++ } + + if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) { + ucsi->sync_val = -EBUSY; +@@ -283,6 +302,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, + { + struct pmic_glink_ucsi *ucsi; + struct device *dev = &adev->dev; ++ struct fwnode_handle *fwnode; + int ret; + + ucsi = devm_kzalloc(dev, sizeof(*ucsi), GFP_KERNEL); +@@ -310,6 +330,38 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, + + ucsi_set_drvdata(ucsi->ucsi, ucsi); + ++ device_for_each_child_node(dev, fwnode) { ++ struct gpio_desc *desc; ++ u32 port; ++ ++ ret = fwnode_property_read_u32(fwnode, "reg", &port); ++ if (ret < 0) { ++ dev_err(dev, "missing reg property of %pOFn\n", fwnode); ++ return ret; ++ } ++ ++ if (port >= PMIC_GLINK_MAX_PORTS) { ++ dev_warn(dev, "invalid connector number, ignoring\n"); ++ continue; ++ } ++ ++ desc = devm_gpiod_get_index_optional(&adev->dev, "orientation", port, GPIOD_IN); ++ ++ /* If GPIO isn't found, continue */ ++ if (!desc) ++ continue; ++ ++ if (IS_ERR(desc)) ++ return dev_err_probe(dev, PTR_ERR(desc), ++ "unable to acquire orientation gpio\n"); ++ ucsi->port_orientation[port] = desc; ++ ++ ucsi->port_switch[port] = fwnode_typec_switch_get(fwnode); ++ if (IS_ERR(ucsi->port_switch[port])) ++ return dev_err_probe(dev, PTR_ERR(ucsi->port_switch[port]), ++ "failed to acquire orientation-switch\n"); ++ } ++ + ucsi->client = devm_pmic_glink_register_client(dev, + PMIC_GLINK_OWNER_USBC, + pmic_glink_ucsi_callback, +-- +2.42.0 + diff --git a/queue-6.5/vdpa_sim_blk-allocate-the-buffer-zeroed.patch b/queue-6.5/vdpa_sim_blk-allocate-the-buffer-zeroed.patch new file mode 100644 index 00000000000..0e28901a837 --- /dev/null +++ b/queue-6.5/vdpa_sim_blk-allocate-the-buffer-zeroed.patch @@ -0,0 +1,53 @@ +From 14ed877d7f0b4c57bb65ac73905c5aeb24f6f3b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Oct 2023 15:43:39 +0100 +Subject: vdpa_sim_blk: allocate the buffer zeroed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Stefano Garzarella + +[ Upstream commit 0d82410252ea324f0064e75b9865bb74cccc1dda ] + +Deleting and recreating a device can lead to having the same +content as the old device, so let's always allocate buffers +completely zeroed out. + +Fixes: abebb16254b3 ("vdpa_sim_blk: support shared backend") +Suggested-by: Qing Wang +Signed-off-by: Stefano Garzarella +Message-Id: <20231031144339.121453-1-sgarzare@redhat.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/vdpa/vdpa_sim/vdpa_sim_blk.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c +index b3a3cb1657955..b137f36793439 100644 +--- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c ++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c +@@ -437,7 +437,7 @@ static int vdpasim_blk_dev_add(struct vdpa_mgmt_dev *mdev, const char *name, + if (blk->shared_backend) { + blk->buffer = shared_buffer; + } else { +- blk->buffer = kvmalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT, ++ blk->buffer = kvzalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT, + GFP_KERNEL); + if (!blk->buffer) { + ret = -ENOMEM; +@@ -495,7 +495,7 @@ static int __init vdpasim_blk_init(void) + goto parent_err; + + if (shared_backend) { +- shared_buffer = kvmalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT, ++ shared_buffer = kvzalloc(VDPASIM_BLK_CAPACITY << SECTOR_SHIFT, + GFP_KERNEL); + if (!shared_buffer) { + ret = -ENOMEM; +-- +2.42.0 + diff --git a/queue-6.5/vhost-vdpa-fix-use-after-free-in-vhost_vdpa_probe.patch b/queue-6.5/vhost-vdpa-fix-use-after-free-in-vhost_vdpa_probe.patch new file mode 100644 index 00000000000..8d3146494e9 --- /dev/null +++ b/queue-6.5/vhost-vdpa-fix-use-after-free-in-vhost_vdpa_probe.patch @@ -0,0 +1,38 @@ +From 61593085e7617c73a79e93fceef534436dbfe497 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 15:12:54 +0300 +Subject: vhost-vdpa: fix use after free in vhost_vdpa_probe() + +From: Dan Carpenter + +[ Upstream commit e07754e0a1ea2d63fb29574253d1fd7405607343 ] + +The put_device() calls vhost_vdpa_release_dev() which calls +ida_simple_remove() and frees "v". So this call to +ida_simple_remove() is a use after free and a double free. + +Fixes: ebe6a354fa7e ("vhost-vdpa: Call ida_simple_remove() when failed") +Signed-off-by: Dan Carpenter +Message-Id: +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/vhost/vdpa.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c +index b43e8680eee8d..48357c403867f 100644 +--- a/drivers/vhost/vdpa.c ++++ b/drivers/vhost/vdpa.c +@@ -1498,7 +1498,6 @@ static int vhost_vdpa_probe(struct vdpa_device *vdpa) + + err: + put_device(&v->dev); +- ida_simple_remove(&vhost_vdpa_ida, v->minor); + return r; + } + +-- +2.42.0 + diff --git a/queue-6.5/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch b/queue-6.5/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch new file mode 100644 index 00000000000..c71e45fa5c1 --- /dev/null +++ b/queue-6.5/virtio-blk-fix-implicit-overflow-on-virtio_max_dma_s.patch @@ -0,0 +1,49 @@ +From 27843e22057c33c9928d9c0546c9e100d074436c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 14:10:45 +0800 +Subject: virtio-blk: fix implicit overflow on virtio_max_dma_size + +From: zhenwei pi + +[ Upstream commit fafb51a67fb883eb2dde352539df939a251851be ] + +The following codes have an implicit conversion from size_t to u32: +(u32)max_size = (size_t)virtio_max_dma_size(vdev); + +This may lead overflow, Ex (size_t)4G -> (u32)0. Once +virtio_max_dma_size() has a larger size than U32_MAX, use U32_MAX +instead. + +Signed-off-by: zhenwei pi +Message-Id: <20230904061045.510460-1-pizhenwei@bytedance.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/block/virtio_blk.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 1fe011676d070..4a4b9bad551e8 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -1313,6 +1313,7 @@ static int virtblk_probe(struct virtio_device *vdev) + u16 min_io_size; + u8 physical_block_exp, alignment_offset; + unsigned int queue_depth; ++ size_t max_dma_size; + + if (!vdev->config->get) { + dev_err(&vdev->dev, "%s failure: config access disabled\n", +@@ -1411,7 +1412,8 @@ static int virtblk_probe(struct virtio_device *vdev) + /* No real sector limit. */ + blk_queue_max_hw_sectors(q, UINT_MAX); + +- max_size = virtio_max_dma_size(vdev); ++ max_dma_size = virtio_max_dma_size(vdev); ++ max_size = max_dma_size > U32_MAX ? U32_MAX : max_dma_size; + + /* Host can optionally specify maximum segment size and number of + * segments. */ +-- +2.42.0 + diff --git a/queue-6.5/vsock-read-from-socket-s-error-queue.patch b/queue-6.5/vsock-read-from-socket-s-error-queue.patch new file mode 100644 index 00000000000..fe00f414d45 --- /dev/null +++ b/queue-6.5/vsock-read-from-socket-s-error-queue.patch @@ -0,0 +1,97 @@ +From aec6f1ef6550eca0c1572af72b23dff7452b9449 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 22:15:14 +0300 +Subject: vsock: read from socket's error queue + +From: Arseniy Krasnov + +[ Upstream commit 49dbe25adac42d3e06f65d1420946bec65896222 ] + +This adds handling of MSG_ERRQUEUE input flag in receive call. This flag +is used to read socket's error queue instead of data queue. Possible +scenario of error queue usage is receiving completions for transmission +with MSG_ZEROCOPY flag. This patch also adds new defines: 'SOL_VSOCK' +and 'VSOCK_RECVERR'. + +Signed-off-by: Arseniy Krasnov +Reviewed-by: Stefano Garzarella +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/socket.h | 1 + + include/uapi/linux/vm_sockets.h | 17 +++++++++++++++++ + net/vmw_vsock/af_vsock.c | 6 ++++++ + 3 files changed, 24 insertions(+) + +diff --git a/include/linux/socket.h b/include/linux/socket.h +index 39b74d83c7c4a..cfcb7e2c3813f 100644 +--- a/include/linux/socket.h ++++ b/include/linux/socket.h +@@ -383,6 +383,7 @@ struct ucred { + #define SOL_MPTCP 284 + #define SOL_MCTP 285 + #define SOL_SMC 286 ++#define SOL_VSOCK 287 + + /* IPX options */ + #define IPX_TYPE 1 +diff --git a/include/uapi/linux/vm_sockets.h b/include/uapi/linux/vm_sockets.h +index c60ca33eac594..ed07181d4eff9 100644 +--- a/include/uapi/linux/vm_sockets.h ++++ b/include/uapi/linux/vm_sockets.h +@@ -191,4 +191,21 @@ struct sockaddr_vm { + + #define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) + ++/* MSG_ZEROCOPY notifications are encoded in the standard error format, ++ * sock_extended_err. See Documentation/networking/msg_zerocopy.rst in ++ * kernel source tree for more details. ++ */ ++ ++/* 'cmsg_level' field value of 'struct cmsghdr' for notification parsing ++ * when MSG_ZEROCOPY flag is used on transmissions. ++ */ ++ ++#define SOL_VSOCK 287 ++ ++/* 'cmsg_type' field value of 'struct cmsghdr' for notification parsing ++ * when MSG_ZEROCOPY flag is used on transmissions. ++ */ ++ ++#define VSOCK_RECVERR 1 ++ + #endif /* _UAPI_VM_SOCKETS_H */ +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 020cf17ab7e47..ccd8cefeea7ba 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -89,6 +89,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -110,6 +111,7 @@ + #include + #include + #include ++#include + + static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); + static void vsock_sk_destruct(struct sock *sk); +@@ -2134,6 +2136,10 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + int err; + + sk = sock->sk; ++ ++ if (unlikely(flags & MSG_ERRQUEUE)) ++ return sock_recv_errqueue(sk, msg, len, SOL_VSOCK, VSOCK_RECVERR); ++ + vsk = vsock_sk(sk); + err = 0; + +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch b/queue-6.5/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch new file mode 100644 index 00000000000..4e440801c4a --- /dev/null +++ b/queue-6.5/wifi-ath10k-don-t-touch-the-ce-interrupt-registers-a.patch @@ -0,0 +1,122 @@ +From ecb35a8f0c7cf0740bdab898838692e6c6253384 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Sep 2023 07:54:48 +0300 +Subject: wifi: ath10k: Don't touch the CE interrupt registers after power up + +From: Douglas Anderson + +[ Upstream commit 170c75d43a77dc937c58f07ecf847ba1b42ab74e ] + +As talked about in commit d66d24ac300c ("ath10k: Keep track of which +interrupts fired, don't poll them"), if we access the copy engine +register at a bad time then ath10k can go boom. However, it's not +necessarily easy to know when it's safe to access them. + +The ChromeOS test labs saw a crash that looked like this at +shutdown/reboot time (on a chromeos-5.15 kernel, but likely the +problem could also reproduce upstream): + +Internal error: synchronous external abort: 96000010 [#1] PREEMPT SMP +... +CPU: 4 PID: 6168 Comm: reboot Not tainted 5.15.111-lockdep-19350-g1d624fe6758f #1 010b9b233ab055c27c6dc88efb0be2f4e9e86f51 +Hardware name: Google Kingoftown (DT) +... +pc : ath10k_snoc_read32+0x50/0x74 [ath10k_snoc] +lr : ath10k_snoc_read32+0x24/0x74 [ath10k_snoc] +... +Call trace: +ath10k_snoc_read32+0x50/0x74 [ath10k_snoc ...] +ath10k_ce_disable_interrupt+0x190/0x65c [ath10k_core ...] +ath10k_ce_disable_interrupts+0x8c/0x120 [ath10k_core ...] +ath10k_snoc_hif_stop+0x78/0x660 [ath10k_snoc ...] +ath10k_core_stop+0x13c/0x1ec [ath10k_core ...] +ath10k_halt+0x398/0x5b0 [ath10k_core ...] +ath10k_stop+0xfc/0x1a8 [ath10k_core ...] +drv_stop+0x148/0x6b4 [mac80211 ...] +ieee80211_stop_device+0x70/0x80 [mac80211 ...] +ieee80211_do_stop+0x10d8/0x15b0 [mac80211 ...] +ieee80211_stop+0x144/0x1a0 [mac80211 ...] +__dev_close_many+0x1e8/0x2c0 +dev_close_many+0x198/0x33c +dev_close+0x140/0x210 +cfg80211_shutdown_all_interfaces+0xc8/0x1e0 [cfg80211 ...] +ieee80211_remove_interfaces+0x118/0x5c4 [mac80211 ...] +ieee80211_unregister_hw+0x64/0x1f4 [mac80211 ...] +ath10k_mac_unregister+0x4c/0xf0 [ath10k_core ...] +ath10k_core_unregister+0x80/0xb0 [ath10k_core ...] +ath10k_snoc_free_resources+0xb8/0x1ec [ath10k_snoc ...] +ath10k_snoc_shutdown+0x98/0xd0 [ath10k_snoc ...] +platform_shutdown+0x7c/0xa0 +device_shutdown+0x3e0/0x58c +kernel_restart_prepare+0x68/0xa0 +kernel_restart+0x28/0x7c + +Though there's no known way to reproduce the problem, it makes sense +that it would be the same issue where we're trying to access copy +engine registers when it's not allowed. + +Let's fix this by changing how we "disable" the interrupts. Instead of +tweaking the copy engine registers we'll just use disable_irq() and +enable_irq(). Then we'll configure the interrupts once at power up +time. + +Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1 + +Signed-off-by: Douglas Anderson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230630151842.1.If764ede23c4e09a43a842771c2ddf99608f25f8e@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/snoc.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c +index 26214c00cd0d7..2c39bad7ebfb9 100644 +--- a/drivers/net/wireless/ath/ath10k/snoc.c ++++ b/drivers/net/wireless/ath/ath10k/snoc.c +@@ -828,12 +828,20 @@ static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar, + + static inline void ath10k_snoc_irq_disable(struct ath10k *ar) + { +- ath10k_ce_disable_interrupts(ar); ++ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); ++ int id; ++ ++ for (id = 0; id < CE_COUNT_MAX; id++) ++ disable_irq(ar_snoc->ce_irqs[id].irq_line); + } + + static inline void ath10k_snoc_irq_enable(struct ath10k *ar) + { +- ath10k_ce_enable_interrupts(ar); ++ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); ++ int id; ++ ++ for (id = 0; id < CE_COUNT_MAX; id++) ++ enable_irq(ar_snoc->ce_irqs[id].irq_line); + } + + static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe) +@@ -1090,6 +1098,8 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar, + goto err_free_rri; + } + ++ ath10k_ce_enable_interrupts(ar); ++ + return 0; + + err_free_rri: +@@ -1253,8 +1263,8 @@ static int ath10k_snoc_request_irq(struct ath10k *ar) + + for (id = 0; id < CE_COUNT_MAX; id++) { + ret = request_irq(ar_snoc->ce_irqs[id].irq_line, +- ath10k_snoc_per_engine_handler, 0, +- ce_name[id], ar); ++ ath10k_snoc_per_engine_handler, ++ IRQF_NO_AUTOEN, ce_name[id], ar); + if (ret) { + ath10k_err(ar, + "failed to register IRQ handler for CE %d: %d\n", +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath10k-fix-clang-specific-fortify-warning.patch b/queue-6.5/wifi-ath10k-fix-clang-specific-fortify-warning.patch new file mode 100644 index 00000000000..70258a0d268 --- /dev/null +++ b/queue-6.5/wifi-ath10k-fix-clang-specific-fortify-warning.patch @@ -0,0 +1,62 @@ +From 6d0175804fdce4cea6d70529eba816ac12dfa81c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:36:02 +0300 +Subject: wifi: ath10k: fix clang-specific fortify warning + +From: Dmitry Antipov + +[ Upstream commit cb4c132ebfeac5962f7258ffc831caa0c4dada1a ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/ath/ath10k/debug.c:8: +In file included from ./include/linux/module.h:13: +In file included from ./include/linux/stat.h:19: +In file included from ./include/linux/time.h:60: +In file included from ./include/linux/time32.h:13: +In file included from ./include/linux/timex.h:67: +In file included from ./arch/x86/include/asm/timex.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'ath10k_debug_get_et_strings()' where +fortification logic inteprets call to 'memcpy()' as an attempt to copy +the whole 'ath10k_gstrings_stats' array from it's first member and so +issues an overread warning. This warning may be silenced by passing +an address of the whole array and not the first member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230829093652.234537-1-dmantipov@yandex.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/debug.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c +index f9518e1c99039..fe89bc61e5317 100644 +--- a/drivers/net/wireless/ath/ath10k/debug.c ++++ b/drivers/net/wireless/ath/ath10k/debug.c +@@ -1140,7 +1140,7 @@ void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *ath10k_gstrings_stats, ++ memcpy(data, ath10k_gstrings_stats, + sizeof(ath10k_gstrings_stats)); + } + +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath12k-fix-possible-out-of-bound-read-in-ath12k.patch b/queue-6.5/wifi-ath12k-fix-possible-out-of-bound-read-in-ath12k.patch new file mode 100644 index 00000000000..b34a7bc6c97 --- /dev/null +++ b/queue-6.5/wifi-ath12k-fix-possible-out-of-bound-read-in-ath12k.patch @@ -0,0 +1,68 @@ +From 0d83af33865d15690879503aa75fa6c087ea5be0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 09:56:02 +0800 +Subject: wifi: ath12k: fix possible out-of-bound read in + ath12k_htt_pull_ppdu_stats() + +From: Baochen Qiang + +[ Upstream commit 1bc44a505a229bb1dd4957e11aa594edeea3690e ] + +len is extracted from HTT message and could be an unexpected value in +case errors happen, so add validation before using to avoid possible +out-of-bound read in the following message iteration and parsing. + +The same issue also applies to ppdu_info->ppdu_stats.common.num_users, +so validate it before using too. + +These are found during code review. + +Compile test only. + +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230901015602.45112-1-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_rx.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index 73edcb1908b91..8dd744c381eeb 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -1555,6 +1555,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, + + msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data; + len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE); ++ if (len > (skb->len - struct_size(msg, data, 0))) { ++ ath12k_warn(ab, ++ "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n", ++ len, skb->len); ++ return -EINVAL; ++ } ++ + pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID); + ppdu_id = le32_to_cpu(msg->ppdu_id); + +@@ -1583,6 +1590,16 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab, + goto exit; + } + ++ if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) { ++ spin_unlock_bh(&ar->data_lock); ++ ath12k_warn(ab, ++ "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n", ++ ppdu_info->ppdu_stats.common.num_users, ++ HTT_PPDU_STATS_MAX_USERS); ++ ret = -EINVAL; ++ goto exit; ++ } ++ + /* back up data rate tlv for all peers */ + if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && + (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) && +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath12k-fix-possible-out-of-bound-write-in-ath12.patch b/queue-6.5/wifi-ath12k-fix-possible-out-of-bound-write-in-ath12.patch new file mode 100644 index 00000000000..bf1eec817da --- /dev/null +++ b/queue-6.5/wifi-ath12k-fix-possible-out-of-bound-write-in-ath12.patch @@ -0,0 +1,47 @@ +From 7500583ca7ab5c5fa38f4efafef0ada34f7046be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Sep 2023 16:43:42 +0300 +Subject: wifi: ath12k: fix possible out-of-bound write in + ath12k_wmi_ext_hal_reg_caps() + +From: Baochen Qiang + +[ Upstream commit b302dce3d9edea5b93d1902a541684a967f3c63c ] + +reg_cap.phy_id is extracted from WMI event and could be an unexpected value +in case some errors happen. As a result out-of-bound write may occur to +soc->hal_reg_cap. Fix it by validating reg_cap.phy_id before using it. + +This is found during code review. + +Compile tested only. + +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230830020716.5420-1-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/wmi.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index eebc5a65ce3b4..416b22fa53ebf 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -3799,6 +3799,12 @@ static int ath12k_wmi_ext_hal_reg_caps(struct ath12k_base *soc, + ath12k_warn(soc, "failed to extract reg cap %d\n", i); + return ret; + } ++ ++ if (reg_cap.phy_id >= MAX_RADIOS) { ++ ath12k_warn(soc, "unexpected phy id %u\n", reg_cap.phy_id); ++ return -EINVAL; ++ } ++ + soc->hal_reg_cap[reg_cap.phy_id] = reg_cap; + } + return 0; +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath12k-ignore-fragments-from-uninitialized-peer.patch b/queue-6.5/wifi-ath12k-ignore-fragments-from-uninitialized-peer.patch new file mode 100644 index 00000000000..6ac7fd84070 --- /dev/null +++ b/queue-6.5/wifi-ath12k-ignore-fragments-from-uninitialized-peer.patch @@ -0,0 +1,112 @@ +From d99103d6b198ac87e409a2a8f71af45859c9b777 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 08:42:43 +0300 +Subject: wifi: ath12k: Ignore fragments from uninitialized peer in dp + +From: Harshitha Prem + +[ Upstream commit bbc86757ca62423c3b6bd8f7176da1ff43450769 ] + +When max virtual ap interfaces are configured in all the bands with +ACS and hostapd restart is done every 60s, a crash is observed at +random times. + +In the above scenario, a fragmented packet is received for self peer, +for which rx_tid and rx_frags are not initialized in datapath. +While handling this fragment, crash is observed as the rx_frag list +is uninitialized and when we walk in ath12k_dp_rx_h_sort_frags, +skb null leads to exception. + +To address this, before processing received fragments we check +dp_setup_done flag is set to ensure that peer has completed its +dp peer setup for fragment queue, else ignore processing the +fragments. + +Call trace: + PC points to "ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k]" + LR points to "ath12k_dp_process_rx_err+0x480/0xfcc [ath12k]". + The Backtrace obtained is as follows: + ath12k_dp_process_rx_err+0x4e8/0xfcc [ath12k] + ath12k_dp_service_srng+0x78/0x260 [ath12k] + ath12k_pci_write32+0x990/0xb0c [ath12k] + __napi_poll+0x30/0xa4 + net_rx_action+0x118/0x270 + __do_softirq+0x10c/0x244 + irq_exit+0x64/0xb4 + __handle_domain_irq+0x88/0xac + gic_handle_irq+0x74/0xbc + el1_irq+0xf0/0x1c0 + arch_cpu_idle+0x10/0x18 + do_idle+0x104/0x248 + cpu_startup_entry+0x20/0x64 + rest_init+0xd0/0xdc + arch_call_rest_init+0xc/0x14 + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Harshitha Prem +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230821130343.29495-2-quic_hprem@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp.c | 1 + + drivers/net/wireless/ath/ath12k/dp_rx.c | 9 +++++++++ + drivers/net/wireless/ath/ath12k/peer.h | 3 +++ + 3 files changed, 13 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c +index f933896f2a68d..6893466f61f04 100644 +--- a/drivers/net/wireless/ath/ath12k/dp.c ++++ b/drivers/net/wireless/ath/ath12k/dp.c +@@ -38,6 +38,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr) + + ath12k_dp_rx_peer_tid_cleanup(ar, peer); + crypto_free_shash(peer->tfm_mmic); ++ peer->dp_setup_done = false; + spin_unlock_bh(&ab->base_lock); + } + +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index fcb91b8ef00e3..73edcb1908b91 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -2747,6 +2747,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev + } + + peer->tfm_mmic = tfm; ++ peer->dp_setup_done = true; + spin_unlock_bh(&ab->base_lock); + + return 0; +@@ -3213,6 +3214,14 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar, + ret = -ENOENT; + goto out_unlock; + } ++ ++ if (!peer->dp_setup_done) { ++ ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", ++ peer->addr, peer_id); ++ ret = -ENOENT; ++ goto out_unlock; ++ } ++ + rx_tid = &peer->rx_tid[tid]; + + if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || +diff --git a/drivers/net/wireless/ath/ath12k/peer.h b/drivers/net/wireless/ath/ath12k/peer.h +index b296dc0e2f671..c6edb24cbedd8 100644 +--- a/drivers/net/wireless/ath/ath12k/peer.h ++++ b/drivers/net/wireless/ath/ath12k/peer.h +@@ -44,6 +44,9 @@ struct ath12k_peer { + struct ppdu_user_delayba ppdu_stats_delayba; + bool delayba_flag; + bool is_authorized; ++ ++ /* protected by ab->data_lock */ ++ bool dp_setup_done; + }; + + void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id); +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath12k-mhi-fix-potential-memory-leak-in-ath12k_.patch b/queue-6.5/wifi-ath12k-mhi-fix-potential-memory-leak-in-ath12k_.patch new file mode 100644 index 00000000000..a19d934b9db --- /dev/null +++ b/queue-6.5/wifi-ath12k-mhi-fix-potential-memory-leak-in-ath12k_.patch @@ -0,0 +1,60 @@ +From d3202cdac83f556dc364178d4a0a947c3044daf9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Sep 2023 07:54:47 +0300 +Subject: wifi: ath12k: mhi: fix potential memory leak in ath12k_mhi_register() + +From: Ma Ke + +[ Upstream commit 47c27aa7ded4b8ead19b3487cc42a6185b762903 ] + +mhi_alloc_controller() allocates a memory space for mhi_ctrl. When some +errors occur, mhi_ctrl should be freed by mhi_free_controller() and set +ab_pci->mhi_ctrl = NULL. + +We can fix it by calling mhi_free_controller() when the failure happens +and set ab_pci->mhi_ctrl = NULL in all of the places where we call +mhi_free_controller(). + +Signed-off-by: Ma Ke +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230922021036.3604157-1-make_ruc2021@163.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mhi.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c +index 42f1140baa4fe..f83d3e09ae366 100644 +--- a/drivers/net/wireless/ath/ath12k/mhi.c ++++ b/drivers/net/wireless/ath/ath12k/mhi.c +@@ -370,8 +370,7 @@ int ath12k_mhi_register(struct ath12k_pci *ab_pci) + ret = ath12k_mhi_get_msi(ab_pci); + if (ret) { + ath12k_err(ab, "failed to get msi for mhi\n"); +- mhi_free_controller(mhi_ctrl); +- return ret; ++ goto free_controller; + } + + mhi_ctrl->iova_start = 0; +@@ -388,11 +387,15 @@ int ath12k_mhi_register(struct ath12k_pci *ab_pci) + ret = mhi_register_controller(mhi_ctrl, ab->hw_params->mhi_config); + if (ret) { + ath12k_err(ab, "failed to register to mhi bus, err = %d\n", ret); +- mhi_free_controller(mhi_ctrl); +- return ret; ++ goto free_controller; + } + + return 0; ++ ++free_controller: ++ mhi_free_controller(mhi_ctrl); ++ ab_pci->mhi_ctrl = NULL; ++ return ret; + } + + void ath12k_mhi_unregister(struct ath12k_pci *ab_pci) +-- +2.42.0 + diff --git a/queue-6.5/wifi-ath9k-fix-clang-specific-fortify-warnings.patch b/queue-6.5/wifi-ath9k-fix-clang-specific-fortify-warnings.patch new file mode 100644 index 00000000000..a86bb10a7fa --- /dev/null +++ b/queue-6.5/wifi-ath9k-fix-clang-specific-fortify-warnings.patch @@ -0,0 +1,102 @@ +From 13af88fea5e33559a39efd22a266b19e22a6fe33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:38:12 +0300 +Subject: wifi: ath9k: fix clang-specific fortify warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dmitry Antipov + +[ Upstream commit 95f97fe0ac974467ab4da215985a32b2fdf48af0 ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/ath/ath9k/debug.c:17: +In file included from ./include/linux/slab.h:16: +In file included from ./include/linux/gfp.h:7: +In file included from ./include/linux/mmzone.h:8: +In file included from ./include/linux/spinlock.h:56: +In file included from ./include/linux/preempt.h:79: +In file included from ./arch/x86/include/asm/preempt.h:9: +In file included from ./include/linux/thread_info.h:60: +In file included from ./arch/x86/include/asm/thread_info.h:53: +In file included from ./arch/x86/include/asm/cpufeature.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +In file included from drivers/net/wireless/ath/ath9k/htc_drv_debug.c:17: +In file included from drivers/net/wireless/ath/ath9k/htc.h:20: +In file included from ./include/linux/module.h:13: +In file included from ./include/linux/stat.h:19: +In file included from ./include/linux/time.h:60: +In file included from ./include/linux/time32.h:13: +In file included from ./include/linux/timex.h:67: +In file included from ./arch/x86/include/asm/timex.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'ath9k_get_et_strings()' and +'ath9k_htc_get_et_strings()' due to the same reason: fortification logic +inteprets call to 'memcpy()' as an attempt to copy the whole array from +it's first member and so issues an overread warning. These warnings may +be silenced by passing an address of the whole array and not the first +member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Acked-by: Toke Høiland-Jørgensen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230829093856.234584-1-dmantipov@yandex.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath9k/debug.c | 2 +- + drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c +index fb7a2952d0ce8..d9bac1c343490 100644 +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1333,7 +1333,7 @@ void ath9k_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *ath9k_gstrings_stats, ++ memcpy(data, ath9k_gstrings_stats, + sizeof(ath9k_gstrings_stats)); + } + +diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +index c55aab01fff5d..e79bbcd3279af 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +@@ -428,7 +428,7 @@ void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *ath9k_htc_gstrings_stats, ++ memcpy(data, ath9k_htc_gstrings_stats, + sizeof(ath9k_htc_gstrings_stats)); + } + +-- +2.42.0 + diff --git a/queue-6.5/wifi-iwlwifi-mvm-fix-size-check-for-fw_link_id.patch b/queue-6.5/wifi-iwlwifi-mvm-fix-size-check-for-fw_link_id.patch new file mode 100644 index 00000000000..bf7b25315a1 --- /dev/null +++ b/queue-6.5/wifi-iwlwifi-mvm-fix-size-check-for-fw_link_id.patch @@ -0,0 +1,46 @@ +From 015d98f9ccc8e3ddfa2fe83a631bfb8e5e99e779 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 12:16:44 +0300 +Subject: wifi: iwlwifi: mvm: fix size check for fw_link_id + +From: Gregory Greenman + +[ Upstream commit e25bd1853cc8308158d97e5b3696ea3689fa0840 ] + +Check that fw_link_id does not exceed the size of link_id_to_link_conf +array. There's no any codepath that can cause that, but it's still +safer to verify in case fw_link_id gets corrupted. + +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231017115047.3385bd11f423.I2d30fdb464f951c648217553c47901857a0046c7@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/link.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +index 6e1ad65527d12..4ab55a1fcbf04 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c +@@ -60,7 +60,7 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) { + link_info->fw_link_id = iwl_mvm_get_free_fw_link_id(mvm, + mvmvif); +- if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) ++ if (link_info->fw_link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf)) + return -EINVAL; + + rcu_assign_pointer(mvm->link_id_to_link_conf[link_info->fw_link_id], +@@ -243,7 +243,7 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + int ret; + + if (WARN_ON(!link_info || +- link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)) ++ link_info->fw_link_id >= ARRAY_SIZE(mvm->link_id_to_link_conf))) + return -EINVAL; + + RCU_INIT_POINTER(mvm->link_id_to_link_conf[link_info->fw_link_id], +-- +2.42.0 + diff --git a/queue-6.5/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch b/queue-6.5/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch new file mode 100644 index 00000000000..8cb2d37719b --- /dev/null +++ b/queue-6.5/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch @@ -0,0 +1,64 @@ +From 360ef04b9da25b0b734c21e2c5dcc4921a425b64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 14:56:45 +0300 +Subject: wifi: iwlwifi: Use FW rate for non-data frames + +From: Miri Korenblit + +[ Upstream commit 499d02790495958506a64f37ceda7e97345a50a8 ] + +Currently we are setting the rate in the tx cmd for +mgmt frames (e.g. during connection establishment). +This was problematic when sending mgmt frames in eSR mode, +as we don't know what link this frame will be sent on +(This is decided by the FW), so we don't know what is the +lowest rate. +Fix this by not setting the rate in tx cmd and rely +on FW to choose the right one. +Set rate only for injected frames with fixed rate, +or when no sta is given. +Also set for important frames (EAPOL etc.) the High Priority flag. + +Fixes: 055b22e770dd ("iwlwifi: mvm: Set Tx rate and flags when there is not station") +Signed-off-by: Miri Korenblit +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230913145231.6c7e59620ee0.I6eaed3ccdd6dd62b9e664facc484081fc5275843@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 2ede69132fee9..177a4628a913e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -536,16 +536,20 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, + flags |= IWL_TX_FLAGS_ENCRYPT_DIS; + + /* +- * For data packets rate info comes from the fw. Only +- * set rate/antenna during connection establishment or in case +- * no station is given. ++ * For data and mgmt packets rate info comes from the fw. Only ++ * set rate/antenna for injected frames with fixed rate, or ++ * when no sta is given. + */ +- if (!sta || !ieee80211_is_data(hdr->frame_control) || +- mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { ++ if (unlikely(!sta || ++ info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) { + flags |= IWL_TX_FLAGS_CMD_RATE; + rate_n_flags = + iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, + hdr->frame_control); ++ } else if (!ieee80211_is_data(hdr->frame_control) || ++ mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { ++ /* These are important frames */ ++ flags |= IWL_TX_FLAGS_HIGH_PRI; + } + + if (mvm->trans->trans_cfg->device_family >= +-- +2.42.0 + diff --git a/queue-6.5/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch b/queue-6.5/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch new file mode 100644 index 00000000000..4c290fec97e --- /dev/null +++ b/queue-6.5/wifi-mac80211-don-t-return-unset-power-in-ieee80211_.patch @@ -0,0 +1,58 @@ +From 67fd09fdcfa597e6ef99e9e0e74a173837863300 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Feb 2023 10:36:36 +0800 +Subject: wifi: mac80211: don't return unset power in ieee80211_get_tx_power() + +From: Ping-Ke Shih + +[ Upstream commit e160ab85166e77347d0cbe5149045cb25e83937f ] + +We can get a UBSAN warning if ieee80211_get_tx_power() returns the +INT_MIN value mac80211 internally uses for "unset power level". + + UBSAN: signed-integer-overflow in net/wireless/nl80211.c:3816:5 + -2147483648 * 100 cannot be represented in type 'int' + CPU: 0 PID: 20433 Comm: insmod Tainted: G WC OE + Call Trace: + dump_stack+0x74/0x92 + ubsan_epilogue+0x9/0x50 + handle_overflow+0x8d/0xd0 + __ubsan_handle_mul_overflow+0xe/0x10 + nl80211_send_iface+0x688/0x6b0 [cfg80211] + [...] + cfg80211_register_wdev+0x78/0xb0 [cfg80211] + cfg80211_netdev_notifier_call+0x200/0x620 [cfg80211] + [...] + ieee80211_if_add+0x60e/0x8f0 [mac80211] + ieee80211_register_hw+0xda5/0x1170 [mac80211] + +In this case, simply return an error instead, to indicate +that no data is available. + +Cc: Zong-Zhe Yang +Signed-off-by: Ping-Ke Shih +Link: https://lore.kernel.org/r/20230203023636.4418-1-pkshih@realtek.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/cfg.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 0e3a1753a51c6..715da615f0359 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -3121,6 +3121,10 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, + else + *dbm = sdata->vif.bss_conf.txpower; + ++ /* INT_MIN indicates no power level was set yet */ ++ if (*dbm == INT_MIN) ++ return -EINVAL; ++ + return 0; + } + +-- +2.42.0 + diff --git a/queue-6.5/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch b/queue-6.5/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch new file mode 100644 index 00000000000..e3ae6419481 --- /dev/null +++ b/queue-6.5/wifi-mac80211_hwsim-fix-clang-specific-fortify-warni.patch @@ -0,0 +1,64 @@ +From 527c08431ba9dc840ed2146844c6d12aea152778 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:41:01 +0300 +Subject: wifi: mac80211_hwsim: fix clang-specific fortify warning + +From: Dmitry Antipov + +[ Upstream commit cbaccdc42483c65016f1bae89128c08dc17cfb2a ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/virtual/mac80211_hwsim.c:18: +In file included from ./include/linux/slab.h:16: +In file included from ./include/linux/gfp.h:7: +In file included from ./include/linux/mmzone.h:8: +In file included from ./include/linux/spinlock.h:56: +In file included from ./include/linux/preempt.h:79: +In file included from ./arch/x86/include/asm/preempt.h:9: +In file included from ./include/linux/thread_info.h:60: +In file included from ./arch/x86/include/asm/thread_info.h:53: +In file included from ./arch/x86/include/asm/cpufeature.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'mac80211_hwsim_get_et_strings()' where +fortification logic inteprets call to 'memcpy()' as an attempt to copy the +whole 'mac80211_hwsim_gstrings_stats' array from its first member and so +issues an overread warning. This warning may be silenced by passing +an address of the whole array and not the first member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Link: https://lore.kernel.org/r/20230829094140.234636-1-dmantipov@yandex.ru +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/virtual/mac80211_hwsim.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c +index 23307c8baea21..6dc153a267872 100644 +--- a/drivers/net/wireless/virtual/mac80211_hwsim.c ++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c +@@ -3170,7 +3170,7 @@ static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *mac80211_hwsim_gstrings_stats, ++ memcpy(data, mac80211_hwsim_gstrings_stats, + sizeof(mac80211_hwsim_gstrings_stats)); + } + +-- +2.42.0 + diff --git a/queue-6.5/wifi-mt76-mt7921e-support-mt7992-ip-in-xiaomi-redmib.patch b/queue-6.5/wifi-mt76-mt7921e-support-mt7992-ip-in-xiaomi-redmib.patch new file mode 100644 index 00000000000..3cfb728f0fe --- /dev/null +++ b/queue-6.5/wifi-mt76-mt7921e-support-mt7992-ip-in-xiaomi-redmib.patch @@ -0,0 +1,58 @@ +From 2f1d6c646bca9e050598d6cf0eb79cd337b377ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Aug 2023 22:02:41 +0200 +Subject: wifi: mt76: mt7921e: Support MT7992 IP in Xiaomi Redmibook 15 Pro + (2023) + +From: Ingo Rohloff + +[ Upstream commit fce9c967820a72f600abbf061d7077861685a14d ] + +In the Xiaomi Redmibook 15 Pro (2023) laptop I have got, a wifi chip is +used, which according to its PCI Vendor ID is from "ITTIM Technology". + +This chip works flawlessly with the mt7921e module. The driver doesn't +bind to this PCI device, because the Vendor ID from "ITTIM Technology" is +not recognized. + +This patch adds the PCI Vendor ID from "ITTIM Technology" to the list of +PCI Vendor IDs and lets the mt7921e driver bind to the mentioned wifi +chip. + +Signed-off-by: Ingo Rohloff +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 2 ++ + include/linux/pci_ids.h | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +index 95610a117d2f0..ed5a220763ce6 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +@@ -17,6 +17,8 @@ static const struct pci_device_id mt7921_pci_device_table[] = { + .driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM }, + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922), + .driver_data = (kernel_ulong_t)MT7922_FIRMWARE_WM }, ++ { PCI_DEVICE(PCI_VENDOR_ID_ITTIM, 0x7922), ++ .driver_data = (kernel_ulong_t)MT7922_FIRMWARE_WM }, + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0608), + .driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM }, + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0616), +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 7702f078ef4ad..54bc1ca7b66fc 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -180,6 +180,8 @@ + #define PCI_DEVICE_ID_BERKOM_A4T 0xffa4 + #define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO 0xffa8 + ++#define PCI_VENDOR_ID_ITTIM 0x0b48 ++ + #define PCI_VENDOR_ID_COMPAQ 0x0e11 + #define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508 + #define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc +-- +2.42.0 + diff --git a/queue-6.5/wifi-plfxlc-fix-clang-specific-fortify-warning.patch b/queue-6.5/wifi-plfxlc-fix-clang-specific-fortify-warning.patch new file mode 100644 index 00000000000..cc0c6e70ada --- /dev/null +++ b/queue-6.5/wifi-plfxlc-fix-clang-specific-fortify-warning.patch @@ -0,0 +1,62 @@ +From 4e578e9c9aea3f6a0f7983cb4bcb573f0ecafdbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 12:45:31 +0300 +Subject: wifi: plfxlc: fix clang-specific fortify warning + +From: Dmitry Antipov + +[ Upstream commit a763e92c78615ea838f5b9a841398b1d4adb968e ] + +When compiling with clang 16.0.6 and CONFIG_FORTIFY_SOURCE=y, I've +noticed the following (somewhat confusing due to absence of an actual +source code location): + +In file included from drivers/net/wireless/purelifi/plfxlc/mac.c:6: +In file included from ./include/linux/netdevice.h:24: +In file included from ./include/linux/timer.h:6: +In file included from ./include/linux/ktime.h:24: +In file included from ./include/linux/time.h:60: +In file included from ./include/linux/time32.h:13: +In file included from ./include/linux/timex.h:67: +In file included from ./arch/x86/include/asm/timex.h:5: +In file included from ./arch/x86/include/asm/processor.h:23: +In file included from ./arch/x86/include/asm/msr.h:11: +In file included from ./arch/x86/include/asm/cpumask.h:5: +In file included from ./include/linux/cpumask.h:12: +In file included from ./include/linux/bitmap.h:11: +In file included from ./include/linux/string.h:254: +./include/linux/fortify-string.h:592:4: warning: call to '__read_overflow2_field' +declared with 'warning' attribute: detected read beyond size of field (2nd +parameter); maybe use struct_group()? [-Wattribute-warning] + __read_overflow2_field(q_size_field, size); + +The compiler actually complains on 'plfxlc_get_et_strings()' where +fortification logic inteprets call to 'memcpy()' as an attempt to copy +the whole 'et_strings' array from its first member and so issues an +overread warning. This warning may be silenced by passing an address +of the whole array and not the first member to 'memcpy()'. + +Signed-off-by: Dmitry Antipov +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230829094541.234751-1-dmantipov@yandex.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/purelifi/plfxlc/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.c b/drivers/net/wireless/purelifi/plfxlc/mac.c +index 94ee831b5de35..506d2f31efb5a 100644 +--- a/drivers/net/wireless/purelifi/plfxlc/mac.c ++++ b/drivers/net/wireless/purelifi/plfxlc/mac.c +@@ -666,7 +666,7 @@ static void plfxlc_get_et_strings(struct ieee80211_hw *hw, + u32 sset, u8 *data) + { + if (sset == ETH_SS_STATS) +- memcpy(data, *et_strings, sizeof(et_strings)); ++ memcpy(data, et_strings, sizeof(et_strings)); + } + + static void plfxlc_get_et_stats(struct ieee80211_hw *hw, +-- +2.42.0 + diff --git a/queue-6.5/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch b/queue-6.5/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch new file mode 100644 index 00000000000..d6b4217d7df --- /dev/null +++ b/queue-6.5/workqueue-provide-one-lock-class-key-per-work_on_cpu.patch @@ -0,0 +1,299 @@ +From e37d6e48dc7dd0ae50fac5aa87da3669fc831464 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 17:07:02 +0200 +Subject: workqueue: Provide one lock class key per work_on_cpu() callsite + +From: Frederic Weisbecker + +[ Upstream commit 265f3ed077036f053981f5eea0b5b43e7c5b39ff ] + +All callers of work_on_cpu() share the same lock class key for all the +functions queued. As a result the workqueue related locking scenario for +a function A may be spuriously accounted as an inversion against the +locking scenario of function B such as in the following model: + + long A(void *arg) + { + mutex_lock(&mutex); + mutex_unlock(&mutex); + } + + long B(void *arg) + { + } + + void launchA(void) + { + work_on_cpu(0, A, NULL); + } + + void launchB(void) + { + mutex_lock(&mutex); + work_on_cpu(1, B, NULL); + mutex_unlock(&mutex); + } + +launchA and launchB running concurrently have no chance to deadlock. +However the above can be reported by lockdep as a possible locking +inversion because the works containing A() and B() are treated as +belonging to the same locking class. + +The following shows an existing example of such a spurious lockdep splat: + + ====================================================== + WARNING: possible circular locking dependency detected + 6.6.0-rc1-00065-g934ebd6e5359 #35409 Not tainted + ------------------------------------------------------ + kworker/0:1/9 is trying to acquire lock: + ffffffff9bc72f30 (cpu_hotplug_lock){++++}-{0:0}, at: _cpu_down+0x57/0x2b0 + + but task is already holding lock: + ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #2 ((work_completion)(&wfc.work)){+.+.}-{0:0}: + __flush_work+0x83/0x4e0 + work_on_cpu+0x97/0xc0 + rcu_nocb_cpu_offload+0x62/0xb0 + rcu_nocb_toggle+0xd0/0x1d0 + kthread+0xe6/0x120 + ret_from_fork+0x2f/0x40 + ret_from_fork_asm+0x1b/0x30 + + -> #1 (rcu_state.barrier_mutex){+.+.}-{3:3}: + __mutex_lock+0x81/0xc80 + rcu_nocb_cpu_deoffload+0x38/0xb0 + rcu_nocb_toggle+0x144/0x1d0 + kthread+0xe6/0x120 + ret_from_fork+0x2f/0x40 + ret_from_fork_asm+0x1b/0x30 + + -> #0 (cpu_hotplug_lock){++++}-{0:0}: + __lock_acquire+0x1538/0x2500 + lock_acquire+0xbf/0x2a0 + percpu_down_write+0x31/0x200 + _cpu_down+0x57/0x2b0 + __cpu_down_maps_locked+0x10/0x20 + work_for_cpu_fn+0x15/0x20 + process_scheduled_works+0x2a7/0x500 + worker_thread+0x173/0x330 + kthread+0xe6/0x120 + ret_from_fork+0x2f/0x40 + ret_from_fork_asm+0x1b/0x30 + + other info that might help us debug this: + + Chain exists of: + cpu_hotplug_lock --> rcu_state.barrier_mutex --> (work_completion)(&wfc.work) + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock((work_completion)(&wfc.work)); + lock(rcu_state.barrier_mutex); + lock((work_completion)(&wfc.work)); + lock(cpu_hotplug_lock); + + *** DEADLOCK *** + + 2 locks held by kworker/0:1/9: + #0: ffff900481068b38 ((wq_completion)events){+.+.}-{0:0}, at: process_scheduled_works+0x212/0x500 + #1: ffff9e3bc0057e60 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_scheduled_works+0x216/0x500 + + stack backtrace: + CPU: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.6.0-rc1-00065-g934ebd6e5359 #35409 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 + Workqueue: events work_for_cpu_fn + Call Trace: + rcu-torture: rcu_torture_read_exit: Start of episode + + dump_stack_lvl+0x4a/0x80 + check_noncircular+0x132/0x150 + __lock_acquire+0x1538/0x2500 + lock_acquire+0xbf/0x2a0 + ? _cpu_down+0x57/0x2b0 + percpu_down_write+0x31/0x200 + ? _cpu_down+0x57/0x2b0 + _cpu_down+0x57/0x2b0 + __cpu_down_maps_locked+0x10/0x20 + work_for_cpu_fn+0x15/0x20 + process_scheduled_works+0x2a7/0x500 + worker_thread+0x173/0x330 + ? __pfx_worker_thread+0x10/0x10 + kthread+0xe6/0x120 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x2f/0x40 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + include/linux/workqueue.h | 46 +++++++++++++++++++++++++++++++++------ + kernel/workqueue.c | 20 ++++++++++------- + 2 files changed, 51 insertions(+), 15 deletions(-) + +diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h +index 683efe29fa698..ca26c1f94f044 100644 +--- a/include/linux/workqueue.h ++++ b/include/linux/workqueue.h +@@ -222,18 +222,16 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } + * to generate better code. + */ + #ifdef CONFIG_LOCKDEP +-#define __INIT_WORK(_work, _func, _onstack) \ ++#define __INIT_WORK_KEY(_work, _func, _onstack, _key) \ + do { \ +- static struct lock_class_key __key; \ +- \ + __init_work((_work), _onstack); \ + (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ +- lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, &__key, 0); \ ++ lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, (_key), 0); \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->func = (_func); \ + } while (0) + #else +-#define __INIT_WORK(_work, _func, _onstack) \ ++#define __INIT_WORK_KEY(_work, _func, _onstack, _key) \ + do { \ + __init_work((_work), _onstack); \ + (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ +@@ -242,12 +240,22 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } + } while (0) + #endif + ++#define __INIT_WORK(_work, _func, _onstack) \ ++ do { \ ++ static __maybe_unused struct lock_class_key __key; \ ++ \ ++ __INIT_WORK_KEY(_work, _func, _onstack, &__key); \ ++ } while (0) ++ + #define INIT_WORK(_work, _func) \ + __INIT_WORK((_work), (_func), 0) + + #define INIT_WORK_ONSTACK(_work, _func) \ + __INIT_WORK((_work), (_func), 1) + ++#define INIT_WORK_ONSTACK_KEY(_work, _func, _key) \ ++ __INIT_WORK_KEY((_work), (_func), 1, _key) ++ + #define __INIT_DELAYED_WORK(_work, _func, _tflags) \ + do { \ + INIT_WORK(&(_work)->work, (_func)); \ +@@ -683,8 +691,32 @@ static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) + return fn(arg); + } + #else +-long work_on_cpu(int cpu, long (*fn)(void *), void *arg); +-long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg); ++long work_on_cpu_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key); ++/* ++ * A new key is defined for each caller to make sure the work ++ * associated with the function doesn't share its locking class. ++ */ ++#define work_on_cpu(_cpu, _fn, _arg) \ ++({ \ ++ static struct lock_class_key __key; \ ++ \ ++ work_on_cpu_key(_cpu, _fn, _arg, &__key); \ ++}) ++ ++long work_on_cpu_safe_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key); ++ ++/* ++ * A new key is defined for each caller to make sure the work ++ * associated with the function doesn't share its locking class. ++ */ ++#define work_on_cpu_safe(_cpu, _fn, _arg) \ ++({ \ ++ static struct lock_class_key __key; \ ++ \ ++ work_on_cpu_safe_key(_cpu, _fn, _arg, &__key); \ ++}) + #endif /* CONFIG_SMP */ + + #ifdef CONFIG_FREEZER +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index e4a37d7a6752d..a7fcb25417726 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5571,50 +5571,54 @@ static void work_for_cpu_fn(struct work_struct *work) + } + + /** +- * work_on_cpu - run a function in thread context on a particular cpu ++ * work_on_cpu_key - run a function in thread context on a particular cpu + * @cpu: the cpu to run on + * @fn: the function to run + * @arg: the function arg ++ * @key: The lock class key for lock debugging purposes + * + * It is up to the caller to ensure that the cpu doesn't go offline. + * The caller must not hold any locks which would prevent @fn from completing. + * + * Return: The value @fn returns. + */ +-long work_on_cpu(int cpu, long (*fn)(void *), void *arg) ++long work_on_cpu_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key) + { + struct work_for_cpu wfc = { .fn = fn, .arg = arg }; + +- INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); ++ INIT_WORK_ONSTACK_KEY(&wfc.work, work_for_cpu_fn, key); + schedule_work_on(cpu, &wfc.work); + flush_work(&wfc.work); + destroy_work_on_stack(&wfc.work); + return wfc.ret; + } +-EXPORT_SYMBOL_GPL(work_on_cpu); ++EXPORT_SYMBOL_GPL(work_on_cpu_key); + + /** +- * work_on_cpu_safe - run a function in thread context on a particular cpu ++ * work_on_cpu_safe_key - run a function in thread context on a particular cpu + * @cpu: the cpu to run on + * @fn: the function to run + * @arg: the function argument ++ * @key: The lock class key for lock debugging purposes + * + * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold + * any locks which would prevent @fn from completing. + * + * Return: The value @fn returns. + */ +-long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) ++long work_on_cpu_safe_key(int cpu, long (*fn)(void *), ++ void *arg, struct lock_class_key *key) + { + long ret = -ENODEV; + + cpus_read_lock(); + if (cpu_online(cpu)) +- ret = work_on_cpu(cpu, fn, arg); ++ ret = work_on_cpu_key(cpu, fn, arg, key); + cpus_read_unlock(); + return ret; + } +-EXPORT_SYMBOL_GPL(work_on_cpu_safe); ++EXPORT_SYMBOL_GPL(work_on_cpu_safe_key); + #endif /* CONFIG_SMP */ + + #ifdef CONFIG_FREEZER +-- +2.42.0 + diff --git a/queue-6.5/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch b/queue-6.5/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch new file mode 100644 index 00000000000..f9d489af2ee --- /dev/null +++ b/queue-6.5/x86-mm-drop-the-4-mb-restriction-on-minimal-numa-nod.patch @@ -0,0 +1,112 @@ +From c5cade8ecf65846cac5ba33bebd7b6cf940f898b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 12:42:50 +0200 +Subject: x86/mm: Drop the 4 MB restriction on minimal NUMA node memory size + +From: Mike Rapoport (IBM) + +[ Upstream commit a1e2b8b36820d8c91275f207e77e91645b7c6836 ] + +Qi Zheng reported crashes in a production environment and provided a +simplified example as a reproducer: + + | For example, if we use Qemu to start a two NUMA node kernel, + | one of the nodes has 2M memory (less than NODE_MIN_SIZE), + | and the other node has 2G, then we will encounter the + | following panic: + | + | BUG: kernel NULL pointer dereference, address: 0000000000000000 + | <...> + | RIP: 0010:_raw_spin_lock_irqsave+0x22/0x40 + | <...> + | Call Trace: + | + | deactivate_slab() + | bootstrap() + | kmem_cache_init() + | start_kernel() + | secondary_startup_64_no_verify() + +The crashes happen because of inconsistency between the nodemask that +has nodes with less than 4MB as memoryless, and the actual memory fed +into the core mm. + +The commit: + + 9391a3f9c7f1 ("[PATCH] x86_64: Clear more state when ignoring empty node in SRAT parsing") + +... that introduced minimal size of a NUMA node does not explain why +a node size cannot be less than 4MB and what boot failures this +restriction might fix. + +Fixes have been submitted to the core MM code to tighten up the +memory topologies it accepts and to not crash on weird input: + + mm: page_alloc: skip memoryless nodes entirely + mm: memory_hotplug: drop memoryless node from fallback lists + +Andrew has accepted them into the -mm tree, but there are no +stable SHA1's yet. + +This patch drops the limitation for minimal node size on x86: + + - which works around the crash without the fixes to the core MM. + - makes x86 topologies less weird, + - removes an arbitrary and undocumented limitation on NUMA topologies. + +[ mingo: Improved changelog clarity. ] + +Reported-by: Qi Zheng +Tested-by: Mario Casquero +Signed-off-by: Mike Rapoport (IBM) +Signed-off-by: Ingo Molnar +Acked-by: David Hildenbrand +Acked-by: Michal Hocko +Cc: Dave Hansen +Cc: Rik van Riel +Link: https://lore.kernel.org/r/ZS+2qqjEO5/867br@gmail.com +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/numa.h | 7 ------- + arch/x86/mm/numa.c | 7 ------- + 2 files changed, 14 deletions(-) + +diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h +index e3bae2b60a0db..ef2844d691735 100644 +--- a/arch/x86/include/asm/numa.h ++++ b/arch/x86/include/asm/numa.h +@@ -12,13 +12,6 @@ + + #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) + +-/* +- * Too small node sizes may confuse the VM badly. Usually they +- * result from BIOS bugs. So dont recognize nodes as standalone +- * NUMA entities that have less than this amount of RAM listed: +- */ +-#define NODE_MIN_SIZE (4*1024*1024) +- + extern int numa_off; + + /* +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index c01c5506fd4ae..aa39d678fe81d 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -602,13 +602,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) + if (start >= end) + continue; + +- /* +- * Don't confuse VM with a node that doesn't have the +- * minimum amount of memory: +- */ +- if (end && (end - start) < NODE_MIN_SIZE) +- continue; +- + alloc_node_data(nid); + } + +-- +2.42.0 + diff --git a/queue-6.5/x86-retpoline-make-sure-there-are-no-unconverted-ret.patch b/queue-6.5/x86-retpoline-make-sure-there-are-no-unconverted-ret.patch new file mode 100644 index 00000000000..9d7e9a8cdba --- /dev/null +++ b/queue-6.5/x86-retpoline-make-sure-there-are-no-unconverted-ret.patch @@ -0,0 +1,81 @@ +From 7c51c6f139274f290c75f2b0ca42fc5923d2975a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 09:59:46 -0700 +Subject: x86/retpoline: Make sure there are no unconverted return thunks due + to KCSAN + +From: Josh Poimboeuf + +[ Upstream commit 2d7ce49f58dc95495b3e22e45d2be7de909b2c63 ] + +Enabling CONFIG_KCSAN leads to unconverted, default return thunks to +remain after patching. + +As David Kaplan describes in his debugging of the issue, it is caused by +a couple of KCSAN-generated constructors which aren't processed by +objtool: + + "When KCSAN is enabled, GCC generates lots of constructor functions + named _sub_I_00099_0 which call __tsan_init and then return. The + returns in these are generally annotated normally by objtool and fixed + up at runtime. But objtool runs on vmlinux.o and vmlinux.o does not + include a couple of object files that are in vmlinux, like + init/version-timestamp.o and .vmlinux.export.o, both of which contain + _sub_I_00099_0 functions. As a result, the returns in these functions + are not annotated, and the panic occurs when we call one of them in + do_ctors and it uses the default return thunk. + + This difference can be seen by counting the number of these functions in the object files: + $ objdump -d vmlinux.o|grep -c "<_sub_I_00099_0>:" + 2601 + $ objdump -d vmlinux|grep -c "<_sub_I_00099_0>:" + 2603 + + If these functions are only run during kernel boot, there is no + speculation concern." + +Fix it by disabling KCSAN on version-timestamp.o and .vmlinux.export.o +so the extra functions don't get generated. KASAN and GCOV are already +disabled for those files. + + [ bp: Massage commit message. ] + +Closes: https://lore.kernel.org/lkml/20231016214810.GA3942238@dev-arch.thelio-3990X/ +Reported-by: Nathan Chancellor +Signed-off-by: Josh Poimboeuf +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Nick Desaulniers +Acked-by: Marco Elver +Tested-by: Nathan Chancellor +Link: https://lore.kernel.org/r/20231017165946.v4i2d4exyqwqq3bx@treble +Signed-off-by: Sasha Levin +--- + init/Makefile | 1 + + scripts/Makefile.vmlinux | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/init/Makefile b/init/Makefile +index ec557ada3c12e..cbac576c57d63 100644 +--- a/init/Makefile ++++ b/init/Makefile +@@ -60,4 +60,5 @@ include/generated/utsversion.h: FORCE + $(obj)/version-timestamp.o: include/generated/utsversion.h + CFLAGS_version-timestamp.o := -include include/generated/utsversion.h + KASAN_SANITIZE_version-timestamp.o := n ++KCSAN_SANITIZE_version-timestamp.o := n + GCOV_PROFILE_version-timestamp.o := n +diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux +index 3cd6ca15f390d..c9f3e03124d7f 100644 +--- a/scripts/Makefile.vmlinux ++++ b/scripts/Makefile.vmlinux +@@ -19,6 +19,7 @@ quiet_cmd_cc_o_c = CC $@ + + ifdef CONFIG_MODULES + KASAN_SANITIZE_.vmlinux.export.o := n ++KCSAN_SANITIZE_.vmlinux.export.o := n + GCOV_PROFILE_.vmlinux.export.o := n + targets += .vmlinux.export.o + vmlinux: .vmlinux.export.o +-- +2.42.0 + diff --git a/queue-6.5/xen-events-avoid-using-info_for_irq-in-xen_send_ipi_.patch b/queue-6.5/xen-events-avoid-using-info_for_irq-in-xen_send_ipi_.patch new file mode 100644 index 00000000000..865a89b5c49 --- /dev/null +++ b/queue-6.5/xen-events-avoid-using-info_for_irq-in-xen_send_ipi_.patch @@ -0,0 +1,87 @@ +From 370e9b697f71974b55f1dd35ad9ef49c1dd29b99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Oct 2023 13:51:36 +0200 +Subject: xen/events: avoid using info_for_irq() in xen_send_IPI_one() + +From: Juergen Gross + +[ Upstream commit e64e7c74b99ec9e439abca75f522f4b98f220bd1 ] + +xen_send_IPI_one() is being used by cpuhp_report_idle_dead() after +it calls rcu_report_dead(), meaning that any RCU usage by +xen_send_IPI_one() is a bad idea. + +Unfortunately xen_send_IPI_one() is using notify_remote_via_irq() +today, which is using irq_get_chip_data() via info_for_irq(). And +irq_get_chip_data() in turn is using a maple-tree lookup requiring +RCU. + +Avoid this problem by caching the ipi event channels in another +percpu variable, allowing the use notify_remote_via_evtchn() in +xen_send_IPI_one(). + +Fixes: 721255b9826b ("genirq: Use a maple tree for interrupt descriptor management") +Reported-by: David Woodhouse +Signed-off-by: Juergen Gross +Tested-by: David Woodhouse +Acked-by: Stefano Stabellini +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/events/events_base.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index c803714d0f0d1..5de10d291a1cb 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -164,6 +164,8 @@ static DEFINE_PER_CPU(int [NR_VIRQS], virq_to_irq) = {[0 ... NR_VIRQS-1] = -1}; + + /* IRQ <-> IPI mapping */ + static DEFINE_PER_CPU(int [XEN_NR_IPIS], ipi_to_irq) = {[0 ... XEN_NR_IPIS-1] = -1}; ++/* Cache for IPI event channels - needed for hot cpu unplug (avoid RCU usage). */ ++static DEFINE_PER_CPU(evtchn_port_t [XEN_NR_IPIS], ipi_to_evtchn) = {[0 ... XEN_NR_IPIS-1] = 0}; + + /* Event channel distribution data */ + static atomic_t channels_on_cpu[NR_CPUS]; +@@ -366,6 +368,7 @@ static int xen_irq_info_ipi_setup(unsigned cpu, + info->u.ipi = ipi; + + per_cpu(ipi_to_irq, cpu)[ipi] = irq; ++ per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn; + + return xen_irq_info_common_setup(info, irq, IRQT_IPI, evtchn, 0); + } +@@ -981,6 +984,7 @@ static void __unbind_from_irq(unsigned int irq) + break; + case IRQT_IPI: + per_cpu(ipi_to_irq, cpu)[ipi_from_irq(irq)] = -1; ++ per_cpu(ipi_to_evtchn, cpu)[ipi_from_irq(irq)] = 0; + break; + case IRQT_EVTCHN: + dev = info->u.interdomain; +@@ -1631,7 +1635,7 @@ EXPORT_SYMBOL_GPL(evtchn_put); + + void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector) + { +- int irq; ++ evtchn_port_t evtchn; + + #ifdef CONFIG_X86 + if (unlikely(vector == XEN_NMI_VECTOR)) { +@@ -1642,9 +1646,9 @@ void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector) + return; + } + #endif +- irq = per_cpu(ipi_to_irq, cpu)[vector]; +- BUG_ON(irq < 0); +- notify_remote_via_irq(irq); ++ evtchn = per_cpu(ipi_to_evtchn, cpu)[vector]; ++ BUG_ON(evtchn == 0); ++ notify_remote_via_evtchn(evtchn); + } + + struct evtchn_loop_ctrl { +-- +2.42.0 + diff --git a/queue-6.5/xen-events-fix-delayed-eoi-list-handling.patch b/queue-6.5/xen-events-fix-delayed-eoi-list-handling.patch new file mode 100644 index 00000000000..0f4458c11a7 --- /dev/null +++ b/queue-6.5/xen-events-fix-delayed-eoi-list-handling.patch @@ -0,0 +1,47 @@ +From 0bd10e4e0ddaaae65aea53e86450bdb953dfa74d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 17:54:13 +0200 +Subject: xen/events: fix delayed eoi list handling + +From: Juergen Gross + +[ Upstream commit 47d970204054f859f35a2237baa75c2d84fcf436 ] + +When delaying eoi handling of events, the related elements are queued +into the percpu lateeoi list. In case the list isn't empty, the +elements should be sorted by the time when eoi handling is to happen. + +Unfortunately a new element will never be queued at the start of the +list, even if it has a handling time lower than all other list +elements. + +Fix that by handling that case the same way as for an empty list. + +Fixes: e99502f76271 ("xen/events: defer eoi in case of excessive number of events") +Reported-by: Jan Beulich +Signed-off-by: Juergen Gross +Reviewed-by: Oleksandr Tyshchenko +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/events/events_base.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index 5de10d291a1cb..87482b3428bf6 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -604,7 +604,9 @@ static void lateeoi_list_add(struct irq_info *info) + + spin_lock_irqsave(&eoi->eoi_list_lock, flags); + +- if (list_empty(&eoi->eoi_list)) { ++ elem = list_first_entry_or_null(&eoi->eoi_list, struct irq_info, ++ eoi_list); ++ if (!elem || info->eoi_time < elem->eoi_time) { + list_add(&info->eoi_list, &eoi->eoi_list); + mod_delayed_work_on(info->eoi_cpu, system_wq, + &eoi->delayed, delay); +-- +2.42.0 +