From 9712bec5a7c800c69e9f3004a28d3e4abdab54f0 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 3 Apr 2024 11:59:48 -0400 Subject: [PATCH] Fixes for 5.15 Signed-off-by: Sasha Levin --- ...check-status-of-acpi_evaluate_object.patch | 53 +++++ ...nst-int-overflow-for-stack-access-si.patch | 53 +++++ ...m-integrity-fix-out-of-range-warning.patch | 47 ++++ ...use-kmemdup-to-replace-kzalloc-memcp.patch | 43 ++++ ...ping-allocation-in-ixgbe_ipsec_vf_ad.patch | 75 ++++++ ...l-request_irq-after-napi-initialized.patch | 168 ++++++++++++++ ...ige-stop-phy-during-open-error-paths.patch | 50 ++++ ...it-value-in-nci_dev_up-and-nci_ntf_p.patch | 53 +++++ ...-pause-frame-configuration-in-gmp-mo.patch | 46 ++++ .../s390-qeth-handle-deferred-cc1.patch | 116 ++++++++++ ...a-helper-sas_get_sas_addr_and_dev_ty.patch | 62 +++++ ...disk-not-being-scanned-in-after-bein.patch | 116 ++++++++++ ...ibsas-introduce-struct-smp_disc_resp.patch | 217 ++++++++++++++++++ .../scsi-usb-call-scsi_done-directly.patch | 109 +++++++++ ...scsi-usb-stop-using-the-scsi-pointer.patch | 216 +++++++++++++++++ queue-5.15/series | 18 ++ ...-terminate-timers-for-kernel-sockets.patch | 138 +++++++++++ ...nodev-when-submit-urbs-fail-with-dev.patch | 154 +++++++++++++ ...mvm-rfi-fix-potential-response-leaks.patch | 50 ++++ 19 files changed, 1784 insertions(+) create mode 100644 queue-5.15/acpica-debugger-check-status-of-acpi_evaluate_object.patch create mode 100644 queue-5.15/bpf-protect-against-int-overflow-for-stack-access-si.patch create mode 100644 queue-5.15/dm-integrity-fix-out-of-range-warning.patch create mode 100644 queue-5.15/iwlwifi-mvm-rfi-use-kmemdup-to-replace-kzalloc-memcp.patch create mode 100644 queue-5.15/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch create mode 100644 queue-5.15/mlxbf_gige-call-request_irq-after-napi-initialized.patch create mode 100644 queue-5.15/mlxbf_gige-stop-phy-during-open-error-paths.patch create mode 100644 queue-5.15/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch create mode 100644 queue-5.15/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch create mode 100644 queue-5.15/s390-qeth-handle-deferred-cc1.patch create mode 100644 queue-5.15/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch create mode 100644 queue-5.15/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch create mode 100644 queue-5.15/scsi-libsas-introduce-struct-smp_disc_resp.patch create mode 100644 queue-5.15/scsi-usb-call-scsi_done-directly.patch create mode 100644 queue-5.15/scsi-usb-stop-using-the-scsi-pointer.patch create mode 100644 queue-5.15/tcp-properly-terminate-timers-for-kernel-sockets.patch create mode 100644 queue-5.15/usb-uas-return-enodev-when-submit-urbs-fail-with-dev.patch create mode 100644 queue-5.15/wifi-iwlwifi-mvm-rfi-fix-potential-response-leaks.patch diff --git a/queue-5.15/acpica-debugger-check-status-of-acpi_evaluate_object.patch b/queue-5.15/acpica-debugger-check-status-of-acpi_evaluate_object.patch new file mode 100644 index 00000000000..7019b983eef --- /dev/null +++ b/queue-5.15/acpica-debugger-check-status-of-acpi_evaluate_object.patch @@ -0,0 +1,53 @@ +From c7718fc618b440529df335a2730fdb5775c6ed00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Mar 2024 21:07:53 +0300 +Subject: ACPICA: debugger: check status of acpi_evaluate_object() in + acpi_db_walk_for_fields() + +From: Nikita Kiryushin + +[ Upstream commit 40e2710860e57411ab57a1529c5a2748abbe8a19 ] + +ACPICA commit 9061cd9aa131205657c811a52a9f8325a040c6c9 + +Errors in acpi_evaluate_object() can lead to incorrect state of buffer. + +This can lead to access to data in previously ACPI_FREEd buffer and +secondary ACPI_FREE to the same buffer later. + +Handle errors in acpi_evaluate_object the same way it is done earlier +with acpi_ns_handle_to_pathname. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Link: https://github.com/acpica/acpica/commit/9061cd9a +Fixes: 5fd033288a86 ("ACPICA: debugger: add command to dump all fields of particular subtype") +Signed-off-by: Nikita Kiryushin +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/dbnames.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c +index b91155ea9c343..c9131259f717b 100644 +--- a/drivers/acpi/acpica/dbnames.c ++++ b/drivers/acpi/acpica/dbnames.c +@@ -550,8 +550,12 @@ acpi_db_walk_for_fields(acpi_handle obj_handle, + ACPI_FREE(buffer.pointer); + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; +- acpi_evaluate_object(obj_handle, NULL, NULL, &buffer); +- ++ status = acpi_evaluate_object(obj_handle, NULL, NULL, &buffer); ++ if (ACPI_FAILURE(status)) { ++ acpi_os_printf("Could Not evaluate object %p\n", ++ obj_handle); ++ return (AE_OK); ++ } + /* + * Since this is a field unit, surround the output in braces + */ +-- +2.43.0 + diff --git a/queue-5.15/bpf-protect-against-int-overflow-for-stack-access-si.patch b/queue-5.15/bpf-protect-against-int-overflow-for-stack-access-si.patch new file mode 100644 index 00000000000..0b591b4c2d9 --- /dev/null +++ b/queue-5.15/bpf-protect-against-int-overflow-for-stack-access-si.patch @@ -0,0 +1,53 @@ +From d781f623f9a670fff938b70c55bd9d0478b92912 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 22:42:45 -0400 +Subject: bpf: Protect against int overflow for stack access size + +From: Andrei Matei + +[ Upstream commit ecc6a2101840177e57c925c102d2d29f260d37c8 ] + +This patch re-introduces protection against the size of access to stack +memory being negative; the access size can appear negative as a result +of overflowing its signed int representation. This should not actually +happen, as there are other protections along the way, but we should +protect against it anyway. One code path was missing such protections +(fixed in the previous patch in the series), causing out-of-bounds array +accesses in check_stack_range_initialized(). This patch causes the +verification of a program with such a non-sensical access size to fail. + +This check used to exist in a more indirect way, but was inadvertendly +removed in a833a17aeac7. + +Fixes: a833a17aeac7 ("bpf: Fix verification of indirect var-off stack access") +Reported-by: syzbot+33f4297b5f927648741a@syzkaller.appspotmail.com +Reported-by: syzbot+aafd0513053a1cbf52ef@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/bpf/CAADnVQLORV5PT0iTAhRER+iLBTkByCYNBYyvBSgjN1T31K+gOw@mail.gmail.com/ +Acked-by: Andrii Nakryiko +Signed-off-by: Andrei Matei +Link: https://lore.kernel.org/r/20240327024245.318299-3-andreimatei1@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index f099c5481b662..008ddb694c8a1 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -4320,6 +4320,11 @@ static int check_stack_access_within_bounds( + err = check_stack_slot_within_bounds(min_off, state, type); + if (!err && max_off > 0) + err = -EINVAL; /* out of stack access into non-negative offsets */ ++ if (!err && access_size < 0) ++ /* access_size should not be negative (or overflow an int); others checks ++ * along the way should have prevented such an access. ++ */ ++ err = -EFAULT; /* invalid negative access size; integer overflow? */ + + if (err) { + if (tnum_is_const(reg->var_off)) { +-- +2.43.0 + diff --git a/queue-5.15/dm-integrity-fix-out-of-range-warning.patch b/queue-5.15/dm-integrity-fix-out-of-range-warning.patch new file mode 100644 index 00000000000..e9bdec092c3 --- /dev/null +++ b/queue-5.15/dm-integrity-fix-out-of-range-warning.patch @@ -0,0 +1,47 @@ +From 844b1a6b9ff4715b1e3c51196f59620d3d9d3919 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Mar 2024 15:30:39 +0100 +Subject: dm integrity: fix out-of-range warning + +From: Arnd Bergmann + +[ Upstream commit 8e91c2342351e0f5ef6c0a704384a7f6fc70c3b2 ] + +Depending on the value of CONFIG_HZ, clang complains about a pointless +comparison: + +drivers/md/dm-integrity.c:4085:12: error: result of comparison of + constant 42949672950 with expression of type + 'unsigned int' is always false + [-Werror,-Wtautological-constant-out-of-range-compare] + if (val >= (uint64_t)UINT_MAX * 1000 / HZ) { + +As the check remains useful for other configurations, shut up the +warning by adding a second type cast to uint64_t. + +Fixes: 468dfca38b1a ("dm integrity: add a bitmap mode") +Signed-off-by: Arnd Bergmann +Reviewed-by: Mikulas Patocka +Reviewed-by: Justin Stitt +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + drivers/md/dm-integrity.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c +index df743650d8a9d..ae372bc44fbfc 100644 +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -4083,7 +4083,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) + } else if (sscanf(opt_string, "sectors_per_bit:%llu%c", &llval, &dummy) == 1) { + log2_sectors_per_bitmap_bit = !llval ? 0 : __ilog2_u64(llval); + } else if (sscanf(opt_string, "bitmap_flush_interval:%u%c", &val, &dummy) == 1) { +- if (val >= (uint64_t)UINT_MAX * 1000 / HZ) { ++ if ((uint64_t)val >= (uint64_t)UINT_MAX * 1000 / HZ) { + r = -EINVAL; + ti->error = "Invalid bitmap_flush_interval argument"; + goto bad; +-- +2.43.0 + diff --git a/queue-5.15/iwlwifi-mvm-rfi-use-kmemdup-to-replace-kzalloc-memcp.patch b/queue-5.15/iwlwifi-mvm-rfi-use-kmemdup-to-replace-kzalloc-memcp.patch new file mode 100644 index 00000000000..f622acb48c6 --- /dev/null +++ b/queue-5.15/iwlwifi-mvm-rfi-use-kmemdup-to-replace-kzalloc-memcp.patch @@ -0,0 +1,43 @@ +From 4493b6d6f7408e93d9bdf7ad96b61ad0c071210b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Oct 2021 14:58:40 +0800 +Subject: iwlwifi: mvm: rfi: use kmemdup() to replace kzalloc + memcpy + +From: Bixuan Cui + +[ Upstream commit 08186e2501eec554cde8bae53b1d1de4d54abdf4 ] + +Fix memdup.cocci warning: +./drivers/net/wireless/intel/iwlwifi/mvm/rfi.c:110:8-15: WARNING +opportunity for kmemdup + +Signed-off-by: Bixuan Cui +Link: https://lore.kernel.org/r/1635317920-84725-1-git-send-email-cuibixuan@linux.alibaba.com +Signed-off-by: Luca Coelho +Stable-dep-of: 06a093807eb7 ("wifi: iwlwifi: mvm: rfi: fix potential response leaks") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/rfi.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c +index 44344216a1a90..1954b4cdb90b4 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c +@@ -107,12 +107,10 @@ struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm) + if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) != resp_size)) + return ERR_PTR(-EIO); + +- resp = kzalloc(resp_size, GFP_KERNEL); ++ resp = kmemdup(cmd.resp_pkt->data, resp_size, GFP_KERNEL); + if (!resp) + return ERR_PTR(-ENOMEM); + +- memcpy(resp, cmd.resp_pkt->data, resp_size); +- + iwl_free_resp(&cmd); + return resp; + } +-- +2.43.0 + diff --git a/queue-5.15/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch b/queue-5.15/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch new file mode 100644 index 00000000000..64846bf7d91 --- /dev/null +++ b/queue-5.15/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch @@ -0,0 +1,75 @@ +From b0f5b1df3f1161eedcad12e812113f9ebb08e0ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Mar 2024 17:02:02 +0100 +Subject: ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa() + +From: Przemek Kitszel + +[ Upstream commit aec806fb4afba5fe80b09e29351379a4292baa43 ] + +Change kzalloc() flags used in ixgbe_ipsec_vf_add_sa() to GFP_ATOMIC, to +avoid sleeping in IRQ context. + +Dan Carpenter, with the help of Smatch, has found following issue: +The patch eda0333ac293: "ixgbe: add VF IPsec management" from Aug 13, +2018 (linux-next), leads to the following Smatch static checker +warning: drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c:917 ixgbe_ipsec_vf_add_sa() + warn: sleeping in IRQ context + +The call tree that Smatch is worried about is: +ixgbe_msix_other() <- IRQ handler +-> ixgbe_msg_task() + -> ixgbe_rcv_msg_from_vf() + -> ixgbe_ipsec_vf_add_sa() + +Fixes: eda0333ac293 ("ixgbe: add VF IPsec management") +Reported-by: Dan Carpenter +Link: https://lore.kernel.org/intel-wired-lan/db31a0b0-4d9f-4e6b-aed8-88266eb5665c@moroto.mountain +Reviewed-by: Michal Kubiak +Signed-off-by: Przemek Kitszel +Reviewed-by: Shannon Nelson +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +index 69d11ff7677d6..ac198c00b44f5 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +@@ -909,7 +909,13 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) + goto err_out; + } + +- xs = kzalloc(sizeof(*xs), GFP_KERNEL); ++ algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1); ++ if (unlikely(!algo)) { ++ err = -ENOENT; ++ goto err_out; ++ } ++ ++ xs = kzalloc(sizeof(*xs), GFP_ATOMIC); + if (unlikely(!xs)) { + err = -ENOMEM; + goto err_out; +@@ -925,14 +931,8 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) + memcpy(&xs->id.daddr.a4, sam->addr, sizeof(xs->id.daddr.a4)); + xs->xso.dev = adapter->netdev; + +- algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1); +- if (unlikely(!algo)) { +- err = -ENOENT; +- goto err_xs; +- } +- + aead_len = sizeof(*xs->aead) + IXGBE_IPSEC_KEY_BITS / 8; +- xs->aead = kzalloc(aead_len, GFP_KERNEL); ++ xs->aead = kzalloc(aead_len, GFP_ATOMIC); + if (unlikely(!xs->aead)) { + err = -ENOMEM; + goto err_xs; +-- +2.43.0 + diff --git a/queue-5.15/mlxbf_gige-call-request_irq-after-napi-initialized.patch b/queue-5.15/mlxbf_gige-call-request_irq-after-napi-initialized.patch new file mode 100644 index 00000000000..02890da590d --- /dev/null +++ b/queue-5.15/mlxbf_gige-call-request_irq-after-napi-initialized.patch @@ -0,0 +1,168 @@ +From 8abadbad827e81c8af5b192a1d2a93d9ee1d7cbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 14:36:27 -0400 +Subject: mlxbf_gige: call request_irq() after NAPI initialized + +From: David Thompson + +[ Upstream commit f7442a634ac06b953fc1f7418f307b25acd4cfbc ] + +The mlxbf_gige driver encounters a NULL pointer exception in +mlxbf_gige_open() when kdump is enabled. The sequence to reproduce +the exception is as follows: +a) enable kdump +b) trigger kdump via "echo c > /proc/sysrq-trigger" +c) kdump kernel executes +d) kdump kernel loads mlxbf_gige module +e) the mlxbf_gige module runs its open() as the + the "oob_net0" interface is brought up +f) mlxbf_gige module will experience an exception + during its open(), something like: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 + Mem abort info: + ESR = 0x0000000086000004 + EC = 0x21: IABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x04: level 0 translation fault + user pgtable: 4k pages, 48-bit VAs, pgdp=00000000e29a4000 + [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 + Internal error: Oops: 0000000086000004 [#1] SMP + CPU: 0 PID: 812 Comm: NetworkManager Tainted: G OE 5.15.0-1035-bluefield #37-Ubuntu + Hardware name: https://www.mellanox.com BlueField-3 SmartNIC Main Card/BlueField-3 SmartNIC Main Card, BIOS 4.6.0.13024 Jan 19 2024 + pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : 0x0 + lr : __napi_poll+0x40/0x230 + sp : ffff800008003e00 + x29: ffff800008003e00 x28: 0000000000000000 x27: 00000000ffffffff + x26: ffff000066027238 x25: ffff00007cedec00 x24: ffff800008003ec8 + x23: 000000000000012c x22: ffff800008003eb7 x21: 0000000000000000 + x20: 0000000000000001 x19: ffff000066027238 x18: 0000000000000000 + x17: ffff578fcb450000 x16: ffffa870b083c7c0 x15: 0000aaab010441d0 + x14: 0000000000000001 x13: 00726f7272655f65 x12: 6769675f6662786c + x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa870b0842398 + x8 : 0000000000000004 x7 : fe5a48b9069706ea x6 : 17fdb11fc84ae0d2 + x5 : d94a82549d594f35 x4 : 0000000000000000 x3 : 0000000000400100 + x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000066027238 + Call trace: + 0x0 + net_rx_action+0x178/0x360 + __do_softirq+0x15c/0x428 + __irq_exit_rcu+0xac/0xec + irq_exit+0x18/0x2c + handle_domain_irq+0x6c/0xa0 + gic_handle_irq+0xec/0x1b0 + call_on_irq_stack+0x20/0x2c + do_interrupt_handler+0x5c/0x70 + el1_interrupt+0x30/0x50 + el1h_64_irq_handler+0x18/0x2c + el1h_64_irq+0x7c/0x80 + __setup_irq+0x4c0/0x950 + request_threaded_irq+0xf4/0x1bc + mlxbf_gige_request_irqs+0x68/0x110 [mlxbf_gige] + mlxbf_gige_open+0x5c/0x170 [mlxbf_gige] + __dev_open+0x100/0x220 + __dev_change_flags+0x16c/0x1f0 + dev_change_flags+0x2c/0x70 + do_setlink+0x220/0xa40 + __rtnl_newlink+0x56c/0x8a0 + rtnl_newlink+0x58/0x84 + rtnetlink_rcv_msg+0x138/0x3c4 + netlink_rcv_skb+0x64/0x130 + rtnetlink_rcv+0x20/0x30 + netlink_unicast+0x2ec/0x360 + netlink_sendmsg+0x278/0x490 + __sock_sendmsg+0x5c/0x6c + ____sys_sendmsg+0x290/0x2d4 + ___sys_sendmsg+0x84/0xd0 + __sys_sendmsg+0x70/0xd0 + __arm64_sys_sendmsg+0x2c/0x40 + invoke_syscall+0x78/0x100 + el0_svc_common.constprop.0+0x54/0x184 + do_el0_svc+0x30/0xac + el0_svc+0x48/0x160 + el0t_64_sync_handler+0xa4/0x12c + el0t_64_sync+0x1a4/0x1a8 + Code: bad PC value + ---[ end trace 7d1c3f3bf9d81885 ]--- + Kernel panic - not syncing: Oops: Fatal exception in interrupt + Kernel Offset: 0x2870a7a00000 from 0xffff800008000000 + PHYS_OFFSET: 0x80000000 + CPU features: 0x0,000005c1,a3332a5a + Memory Limit: none + ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]--- + +The exception happens because there is a pending RX interrupt before the +call to request_irq(RX IRQ) executes. Then, the RX IRQ handler fires +immediately after this request_irq() completes. The RX IRQ handler runs +"napi_schedule()" before NAPI is fully initialized via "netif_napi_add()" +and "napi_enable()", both which happen later in the open() logic. + +The logic in mlxbf_gige_open() must fully initialize NAPI before any calls +to request_irq() execute. + +Fixes: f92e1869d74e ("Add Mellanox BlueField Gigabit Ethernet driver") +Signed-off-by: David Thompson +Reviewed-by: Asmaa Mnebhi +Link: https://lore.kernel.org/r/20240325183627.7641-1-davthompson@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../mellanox/mlxbf_gige/mlxbf_gige_main.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +index 621594061fb57..6b93889900434 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +@@ -141,13 +141,10 @@ static int mlxbf_gige_open(struct net_device *netdev) + control |= MLXBF_GIGE_CONTROL_PORT_EN; + writeq(control, priv->base + MLXBF_GIGE_CONTROL); + +- err = mlxbf_gige_request_irqs(priv); +- if (err) +- return err; + mlxbf_gige_cache_stats(priv); + err = mlxbf_gige_clean_port(priv); + if (err) +- goto free_irqs; ++ return err; + + /* Clear driver's valid_polarity to match hardware, + * since the above call to clean_port() resets the +@@ -168,6 +165,10 @@ static int mlxbf_gige_open(struct net_device *netdev) + napi_enable(&priv->napi); + netif_start_queue(netdev); + ++ err = mlxbf_gige_request_irqs(priv); ++ if (err) ++ goto napi_deinit; ++ + /* Set bits in INT_EN that we care about */ + int_en = MLXBF_GIGE_INT_EN_HW_ACCESS_ERROR | + MLXBF_GIGE_INT_EN_TX_CHECKSUM_INPUTS | +@@ -184,14 +185,17 @@ static int mlxbf_gige_open(struct net_device *netdev) + + return 0; + ++napi_deinit: ++ netif_stop_queue(netdev); ++ napi_disable(&priv->napi); ++ netif_napi_del(&priv->napi); ++ mlxbf_gige_rx_deinit(priv); ++ + tx_deinit: + mlxbf_gige_tx_deinit(priv); + + phy_deinit: + phy_stop(phydev); +- +-free_irqs: +- mlxbf_gige_free_irqs(priv); + return err; + } + +-- +2.43.0 + diff --git a/queue-5.15/mlxbf_gige-stop-phy-during-open-error-paths.patch b/queue-5.15/mlxbf_gige-stop-phy-during-open-error-paths.patch new file mode 100644 index 00000000000..6264b5ff465 --- /dev/null +++ b/queue-5.15/mlxbf_gige-stop-phy-during-open-error-paths.patch @@ -0,0 +1,50 @@ +From 85f13f9d3d0f6aee1c47a5ef9fcd6305d59c959a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Mar 2024 15:31:17 -0400 +Subject: mlxbf_gige: stop PHY during open() error paths + +From: David Thompson + +[ Upstream commit d6c30c5a168f8586b8bcc0d8e42e2456eb05209b ] + +The mlxbf_gige_open() routine starts the PHY as part of normal +initialization. The mlxbf_gige_open() routine must stop the +PHY during its error paths. + +Fixes: f92e1869d74e ("Add Mellanox BlueField Gigabit Ethernet driver") +Signed-off-by: David Thompson +Reviewed-by: Asmaa Mnebhi +Reviewed-by: Andrew Lunn +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +index 679415a64f25c..621594061fb57 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +@@ -159,7 +159,7 @@ static int mlxbf_gige_open(struct net_device *netdev) + + err = mlxbf_gige_tx_init(priv); + if (err) +- goto free_irqs; ++ goto phy_deinit; + err = mlxbf_gige_rx_init(priv); + if (err) + goto tx_deinit; +@@ -187,6 +187,9 @@ static int mlxbf_gige_open(struct net_device *netdev) + tx_deinit: + mlxbf_gige_tx_deinit(priv); + ++phy_deinit: ++ phy_stop(phydev); ++ + free_irqs: + mlxbf_gige_free_irqs(priv); + return err; +-- +2.43.0 + diff --git a/queue-5.15/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch b/queue-5.15/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch new file mode 100644 index 00000000000..c9b3d9f4491 --- /dev/null +++ b/queue-5.15/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch @@ -0,0 +1,53 @@ +From 731633b99c7dd39e2b11130c2fddead81981cf67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Mar 2024 09:54:10 +0900 +Subject: nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet + +From: Ryosuke Yasuoka + +[ Upstream commit d24b03535e5eb82e025219c2f632b485409c898f ] + +syzbot reported the following uninit-value access issue [1][2]: + +nci_rx_work() parses and processes received packet. When the payload +length is zero, each message type handler reads uninitialized payload +and KMSAN detects this issue. The receipt of a packet with a zero-size +payload is considered unexpected, and therefore, such packets should be +silently discarded. + +This patch resolved this issue by checking payload size before calling +each message type handler codes. + +Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation") +Reported-and-tested-by: syzbot+7ea9413ea6749baf5574@syzkaller.appspotmail.com +Reported-and-tested-by: syzbot+29b5ca705d2e0f4a44d2@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7ea9413ea6749baf5574 [1] +Closes: https://syzkaller.appspot.com/bug?extid=29b5ca705d2e0f4a44d2 [2] +Signed-off-by: Ryosuke Yasuoka +Reviewed-by: Jeremy Cline +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/nfc/nci/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c +index 419a1d0ba4c92..2a821f2b2ffe8 100644 +--- a/net/nfc/nci/core.c ++++ b/net/nfc/nci/core.c +@@ -1516,6 +1516,11 @@ static void nci_rx_work(struct work_struct *work) + nfc_send_to_raw_sock(ndev->nfc_dev, skb, + RAW_PAYLOAD_NCI, NFC_DIRECTION_RX); + ++ if (!nci_plen(skb->data)) { ++ kfree_skb(skb); ++ break; ++ } ++ + /* Process frame */ + switch (nci_mt(skb->data)) { + case NCI_MT_RSP_PKT: +-- +2.43.0 + diff --git a/queue-5.15/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch b/queue-5.15/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch new file mode 100644 index 00000000000..167508a929d --- /dev/null +++ b/queue-5.15/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch @@ -0,0 +1,46 @@ +From 4ce692a96a26c1428414c1f603497307773b79e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 10:57:20 +0530 +Subject: Octeontx2-af: fix pause frame configuration in GMP mode + +From: Hariprasad Kelam + +[ Upstream commit 40d4b4807cadd83fb3f46cc8cd67a945b5b25461 ] + +The Octeontx2 MAC block (CGX) has separate data paths (SMU and GMP) for +different speeds, allowing for efficient data transfer. + +The previous patch which added pause frame configuration has a bug due +to which pause frame feature is not working in GMP mode. + +This patch fixes the issue by configurating appropriate registers. + +Fixes: f7e086e754fe ("octeontx2-af: Pause frame configuration at cgx") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240326052720.4441-1-hkelam@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 3ade1a6e2f1e0..4dec201158956 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -787,6 +787,11 @@ static int cgx_lmac_enadis_pause_frm(void *cgxd, int lmac_id, + if (!is_lmac_valid(cgx, lmac_id)) + return -ENODEV; + ++ cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL); ++ cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK; ++ cfg |= rx_pause ? CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK : 0x0; ++ cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg); ++ + cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL); + cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK; + cfg |= rx_pause ? CGX_SMUX_RX_FRM_CTL_CTL_BCK : 0x0; +-- +2.43.0 + diff --git a/queue-5.15/s390-qeth-handle-deferred-cc1.patch b/queue-5.15/s390-qeth-handle-deferred-cc1.patch new file mode 100644 index 00000000000..6dfd9cb9369 --- /dev/null +++ b/queue-5.15/s390-qeth-handle-deferred-cc1.patch @@ -0,0 +1,116 @@ +From 6419442db2bcfb5197414b0c552b7ed57dfa5f83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 12:53:37 +0100 +Subject: s390/qeth: handle deferred cc1 + +From: Alexandra Winter + +[ Upstream commit afb373ff3f54c9d909efc7f810dc80a9742807b2 ] + +The IO subsystem expects a driver to retry a ccw_device_start, when the +subsequent interrupt response block (irb) contains a deferred +condition code 1. + +Symptoms before this commit: +On the read channel we always trigger the next read anyhow, so no +different behaviour here. +On the write channel we may experience timeout errors, because the +expected reply will never be received without the retry. +Other callers of qeth_send_control_data() may wrongly assume that the ccw +was successful, which may cause problems later. + +Note that since +commit 2297791c92d0 ("s390/cio: dont unregister subchannel from child-drivers") +and +commit 5ef1dc40ffa6 ("s390/cio: fix invalid -EBUSY on ccw_device_start") +deferred CC1s are much more likely to occur. See the commit message of the +latter for more background information. + +Fixes: 2297791c92d0 ("s390/cio: dont unregister subchannel from child-drivers") +Signed-off-by: Alexandra Winter +Co-developed-by: Thorsten Winkler +Signed-off-by: Thorsten Winkler +Reviewed-by: Peter Oberparleiter +Link: https://lore.kernel.org/r/20240321115337.3564694-1-wintera@linux.ibm.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core_main.c | 38 +++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 62e7576bff536..c1346c4e2242d 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -1142,6 +1142,20 @@ static int qeth_check_irb_error(struct qeth_card *card, struct ccw_device *cdev, + } + } + ++/** ++ * qeth_irq() - qeth interrupt handler ++ * @cdev: ccw device ++ * @intparm: expect pointer to iob ++ * @irb: Interruption Response Block ++ * ++ * In the good path: ++ * corresponding qeth channel is locked with last used iob as active_cmd. ++ * But this function is also called for error interrupts. ++ * ++ * Caller ensures that: ++ * Interrupts are disabled; ccw device lock is held; ++ * ++ */ + static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, + struct irb *irb) + { +@@ -1183,11 +1197,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, + iob = (struct qeth_cmd_buffer *) (addr_t)intparm; + } + +- qeth_unlock_channel(card, channel); +- + rc = qeth_check_irb_error(card, cdev, irb); + if (rc) { + /* IO was terminated, free its resources. */ ++ qeth_unlock_channel(card, channel); + if (iob) + qeth_cancel_cmd(iob, rc); + return; +@@ -1231,6 +1244,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, + rc = qeth_get_problem(card, cdev, irb); + if (rc) { + card->read_or_write_problem = 1; ++ qeth_unlock_channel(card, channel); + if (iob) + qeth_cancel_cmd(iob, rc); + qeth_clear_ipacmd_list(card); +@@ -1239,6 +1253,26 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, + } + } + ++ if (scsw_cmd_is_valid_cc(&irb->scsw) && irb->scsw.cmd.cc == 1 && iob) { ++ /* channel command hasn't started: retry. ++ * active_cmd is still set to last iob ++ */ ++ QETH_CARD_TEXT(card, 2, "irqcc1"); ++ rc = ccw_device_start_timeout(cdev, __ccw_from_cmd(iob), ++ (addr_t)iob, 0, 0, iob->timeout); ++ if (rc) { ++ QETH_DBF_MESSAGE(2, ++ "ccw retry on %x failed, rc = %i\n", ++ CARD_DEVID(card), rc); ++ QETH_CARD_TEXT_(card, 2, " err%d", rc); ++ qeth_unlock_channel(card, channel); ++ qeth_cancel_cmd(iob, rc); ++ } ++ return; ++ } ++ ++ qeth_unlock_channel(card, channel); ++ + if (iob) { + /* sanity check: */ + if (irb->scsw.cmd.count > iob->length) { +-- +2.43.0 + diff --git a/queue-5.15/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch b/queue-5.15/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch new file mode 100644 index 00000000000..d7f1f635a54 --- /dev/null +++ b/queue-5.15/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch @@ -0,0 +1,62 @@ +From 75e1dbd05bd2edcb5b32bc4919b8beafa12543bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 14:14:12 +0000 +Subject: scsi: libsas: Add a helper sas_get_sas_addr_and_dev_type() + +From: Xingui Yang + +[ Upstream commit a57345279fd311ba679b8083feb0eec5272c7729 ] + +Add a helper to get attached_sas_addr and device type from disc_resp. + +Suggested-by: John Garry +Signed-off-by: Xingui Yang +Link: https://lore.kernel.org/r/20240307141413.48049-2-yangxingui@huawei.com +Reviewed-by: John Garry +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8e68a458bcf5 ("scsi: libsas: Fix disk not being scanned in after being removed") +Signed-off-by: Sasha Levin +--- + drivers/scsi/libsas/sas_expander.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c +index 1b608cb423e0c..6a61a84ce3453 100644 +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -1673,6 +1673,16 @@ int sas_discover_root_expander(struct domain_device *dev) + + /* ---------- Domain revalidation ---------- */ + ++static void sas_get_sas_addr_and_dev_type(struct smp_disc_resp *disc_resp, ++ u8 *sas_addr, ++ enum sas_device_type *type) ++{ ++ memcpy(sas_addr, disc_resp->disc.attached_sas_addr, SAS_ADDR_SIZE); ++ *type = to_dev_type(&disc_resp->disc); ++ if (*type == SAS_PHY_UNUSED) ++ memset(sas_addr, 0, SAS_ADDR_SIZE); ++} ++ + static int sas_get_phy_discover(struct domain_device *dev, + int phy_id, struct smp_disc_resp *disc_resp) + { +@@ -1726,13 +1736,8 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, + return -ENOMEM; + + res = sas_get_phy_discover(dev, phy_id, disc_resp); +- if (res == 0) { +- memcpy(sas_addr, disc_resp->disc.attached_sas_addr, +- SAS_ADDR_SIZE); +- *type = to_dev_type(&disc_resp->disc); +- if (*type == 0) +- memset(sas_addr, 0, SAS_ADDR_SIZE); +- } ++ if (res == 0) ++ sas_get_sas_addr_and_dev_type(disc_resp, sas_addr, type); + kfree(disc_resp); + return res; + } +-- +2.43.0 + diff --git a/queue-5.15/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch b/queue-5.15/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch new file mode 100644 index 00000000000..b7a781fadd1 --- /dev/null +++ b/queue-5.15/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch @@ -0,0 +1,116 @@ +From 01ea12c830e461588628aacc292d8dd7c977a383 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 14:14:13 +0000 +Subject: scsi: libsas: Fix disk not being scanned in after being removed + +From: Xingui Yang + +[ Upstream commit 8e68a458bcf5b5cb9c3624598bae28f08251601f ] + +As of commit d8649fc1c5e4 ("scsi: libsas: Do discovery on empty PHY to +update PHY info"), do discovery will send a new SMP_DISCOVER and update +phy->phy_change_count. We found that if the disk is reconnected and phy +change_count changes at this time, the disk scanning process will not be +triggered. + +Therefore, call sas_set_ex_phy() to update the PHY info with the results of +the last query. And because the previous phy info will be used when calling +sas_unregister_devs_sas_addr(), sas_unregister_devs_sas_addr() should be +called before sas_set_ex_phy(). + +Fixes: d8649fc1c5e4 ("scsi: libsas: Do discovery on empty PHY to update PHY info") +Signed-off-by: Xingui Yang +Link: https://lore.kernel.org/r/20240307141413.48049-3-yangxingui@huawei.com +Reviewed-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/libsas/sas_expander.c | 32 ++++++++++++++++++++---------- + 1 file changed, 22 insertions(+), 10 deletions(-) + +diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c +index 6a61a84ce3453..47043d582d0a3 100644 +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -1999,6 +1999,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, + struct expander_device *ex = &dev->ex_dev; + struct ex_phy *phy = &ex->ex_phy[phy_id]; + enum sas_device_type type = SAS_PHY_UNUSED; ++ struct smp_disc_resp *disc_resp; + u8 sas_addr[SAS_ADDR_SIZE]; + char msg[80] = ""; + int res; +@@ -2010,33 +2011,41 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, + SAS_ADDR(dev->sas_addr), phy_id, msg); + + memset(sas_addr, 0, SAS_ADDR_SIZE); +- res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type); ++ disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); ++ if (!disc_resp) ++ return -ENOMEM; ++ ++ res = sas_get_phy_discover(dev, phy_id, disc_resp); + switch (res) { + case SMP_RESP_NO_PHY: + phy->phy_state = PHY_NOT_PRESENT; + sas_unregister_devs_sas_addr(dev, phy_id, last); +- return res; ++ goto out_free_resp; + case SMP_RESP_PHY_VACANT: + phy->phy_state = PHY_VACANT; + sas_unregister_devs_sas_addr(dev, phy_id, last); +- return res; ++ goto out_free_resp; + case SMP_RESP_FUNC_ACC: + break; + case -ECOMM: + break; + default: +- return res; ++ goto out_free_resp; + } + ++ if (res == 0) ++ sas_get_sas_addr_and_dev_type(disc_resp, sas_addr, &type); ++ + if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) { + phy->phy_state = PHY_EMPTY; + sas_unregister_devs_sas_addr(dev, phy_id, last); + /* +- * Even though the PHY is empty, for convenience we discover +- * the PHY to update the PHY info, like negotiated linkrate. ++ * Even though the PHY is empty, for convenience we update ++ * the PHY info, like negotiated linkrate. + */ +- sas_ex_phy_discover(dev, phy_id); +- return res; ++ if (res == 0) ++ sas_set_ex_phy(dev, phy_id, disc_resp); ++ goto out_free_resp; + } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) && + dev_type_flutter(type, phy->attached_dev_type)) { + struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id); +@@ -2048,7 +2057,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, + action = ", needs recovery"; + pr_debug("ex %016llx phy%02d broadcast flutter%s\n", + SAS_ADDR(dev->sas_addr), phy_id, action); +- return res; ++ goto out_free_resp; + } + + /* we always have to delete the old device when we went here */ +@@ -2057,7 +2066,10 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, + SAS_ADDR(phy->attached_sas_addr)); + sas_unregister_devs_sas_addr(dev, phy_id, last); + +- return sas_discover_new(dev, phy_id); ++ res = sas_discover_new(dev, phy_id); ++out_free_resp: ++ kfree(disc_resp); ++ return res; + } + + /** +-- +2.43.0 + diff --git a/queue-5.15/scsi-libsas-introduce-struct-smp_disc_resp.patch b/queue-5.15/scsi-libsas-introduce-struct-smp_disc_resp.patch new file mode 100644 index 00000000000..c7508c99b15 --- /dev/null +++ b/queue-5.15/scsi-libsas-introduce-struct-smp_disc_resp.patch @@ -0,0 +1,217 @@ +From eaf20826e6c756e966ee6a556fdf0e9ac9f0637e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Jun 2022 11:24:54 +0900 +Subject: scsi: libsas: Introduce struct smp_disc_resp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Damien Le Moal + +[ Upstream commit c3752f44604f3bc4f3ce6e169fa32d16943ff70b ] + +When compiling with gcc 12, several warnings are thrown by gcc when +compiling drivers/scsi/libsas/sas_expander.c, e.g.: + +In function ‘sas_get_phy_change_count’, + inlined from ‘sas_find_bcast_phy.constprop’ at +drivers/scsi/libsas/sas_expander.c:1737:9: +drivers/scsi/libsas/sas_expander.c:1697:39: warning: array subscript +‘struct smp_resp[0]’ is partly outside array bounds of ‘unsigned +char[56]’ [-Warray-bounds] + 1697 | *pcc = disc_resp->disc.change_count; + | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~ + +This is due to the use of the struct smp_resp to aggregate all possible +response types using a union but allocating a response buffer with a size +exactly equal to the size of the response type needed. This leads to access +to fields of struct smp_resp from an allocated memory area that is smaller +than the size of struct smp_resp. + +Fix this by defining struct smp_disc_resp for sas discovery operations. +Since this structure and the generic struct smp_resp are identical for +the little endian and big endian archs, move the definition of these +structures at the end of include/scsi/sas.h to avoid repeating their +definition. + +Link: https://lore.kernel.org/r/20220609022456.409087-2-damien.lemoal@opensource.wdc.com +Reviewed-by: John Garry +Signed-off-by: Damien Le Moal +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8e68a458bcf5 ("scsi: libsas: Fix disk not being scanned in after being removed") +Signed-off-by: Sasha Levin +--- + drivers/scsi/libsas/sas_expander.c | 32 +++++++++++++----------------- + include/scsi/sas.h | 28 +++++++++++--------------- + 2 files changed, 26 insertions(+), 34 deletions(-) + +diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c +index 9ae35631135d8..1b608cb423e0c 100644 +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -192,13 +192,13 @@ static enum sas_device_type to_dev_type(struct discover_resp *dr) + return dr->attached_dev_type; + } + +-static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) ++static void sas_set_ex_phy(struct domain_device *dev, int phy_id, ++ struct smp_disc_resp *disc_resp) + { + enum sas_device_type dev_type; + enum sas_linkrate linkrate; + u8 sas_addr[SAS_ADDR_SIZE]; +- struct smp_resp *resp = rsp; +- struct discover_resp *dr = &resp->disc; ++ struct discover_resp *dr = &disc_resp->disc; + struct sas_ha_struct *ha = dev->port->ha; + struct expander_device *ex = &dev->ex_dev; + struct ex_phy *phy = &ex->ex_phy[phy_id]; +@@ -215,7 +215,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) + BUG_ON(!phy->phy); + } + +- switch (resp->result) { ++ switch (disc_resp->result) { + case SMP_RESP_PHY_VACANT: + phy->phy_state = PHY_VACANT; + break; +@@ -364,12 +364,13 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id) + } + + #define DISCOVER_REQ_SIZE 16 +-#define DISCOVER_RESP_SIZE 56 ++#define DISCOVER_RESP_SIZE sizeof(struct smp_disc_resp) + + static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req, +- u8 *disc_resp, int single) ++ struct smp_disc_resp *disc_resp, ++ int single) + { +- struct discover_resp *dr; ++ struct discover_resp *dr = &disc_resp->disc; + int res; + + disc_req[9] = single; +@@ -378,7 +379,6 @@ static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req, + disc_resp, DISCOVER_RESP_SIZE); + if (res) + return res; +- dr = &((struct smp_resp *)disc_resp)->disc; + if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) { + pr_notice("Found loopback topology, just ignore it!\n"); + return 0; +@@ -392,7 +392,7 @@ int sas_ex_phy_discover(struct domain_device *dev, int single) + struct expander_device *ex = &dev->ex_dev; + int res = 0; + u8 *disc_req; +- u8 *disc_resp; ++ struct smp_disc_resp *disc_resp; + + disc_req = alloc_smp_req(DISCOVER_REQ_SIZE); + if (!disc_req) +@@ -1674,7 +1674,7 @@ int sas_discover_root_expander(struct domain_device *dev) + /* ---------- Domain revalidation ---------- */ + + static int sas_get_phy_discover(struct domain_device *dev, +- int phy_id, struct smp_resp *disc_resp) ++ int phy_id, struct smp_disc_resp *disc_resp) + { + int res; + u8 *disc_req; +@@ -1690,10 +1690,8 @@ static int sas_get_phy_discover(struct domain_device *dev, + disc_resp, DISCOVER_RESP_SIZE); + if (res) + goto out; +- else if (disc_resp->result != SMP_RESP_FUNC_ACC) { ++ if (disc_resp->result != SMP_RESP_FUNC_ACC) + res = disc_resp->result; +- goto out; +- } + out: + kfree(disc_req); + return res; +@@ -1703,7 +1701,7 @@ static int sas_get_phy_change_count(struct domain_device *dev, + int phy_id, int *pcc) + { + int res; +- struct smp_resp *disc_resp; ++ struct smp_disc_resp *disc_resp; + + disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); + if (!disc_resp) +@@ -1721,19 +1719,17 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, + u8 *sas_addr, enum sas_device_type *type) + { + int res; +- struct smp_resp *disc_resp; +- struct discover_resp *dr; ++ struct smp_disc_resp *disc_resp; + + disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); + if (!disc_resp) + return -ENOMEM; +- dr = &disc_resp->disc; + + res = sas_get_phy_discover(dev, phy_id, disc_resp); + if (res == 0) { + memcpy(sas_addr, disc_resp->disc.attached_sas_addr, + SAS_ADDR_SIZE); +- *type = to_dev_type(dr); ++ *type = to_dev_type(&disc_resp->disc); + if (*type == 0) + memset(sas_addr, 0, SAS_ADDR_SIZE); + } +diff --git a/include/scsi/sas.h b/include/scsi/sas.h +index 4726c1bbec659..2f73c24d4c9b9 100644 +--- a/include/scsi/sas.h ++++ b/include/scsi/sas.h +@@ -460,18 +460,6 @@ struct report_phy_sata_resp { + __be32 crc; + } __attribute__ ((packed)); + +-struct smp_resp { +- u8 frame_type; +- u8 function; +- u8 result; +- u8 reserved; +- union { +- struct report_general_resp rg; +- struct discover_resp disc; +- struct report_phy_sata_resp rps; +- }; +-} __attribute__ ((packed)); +- + #elif defined(__BIG_ENDIAN_BITFIELD) + struct sas_identify_frame { + /* Byte 0 */ +@@ -691,6 +679,18 @@ struct report_phy_sata_resp { + __be32 crc; + } __attribute__ ((packed)); + ++#else ++#error "Bitfield order not defined!" ++#endif ++ ++struct smp_disc_resp { ++ u8 frame_type; ++ u8 function; ++ u8 result; ++ u8 reserved; ++ struct discover_resp disc; ++} __attribute__ ((packed)); ++ + struct smp_resp { + u8 frame_type; + u8 function; +@@ -703,8 +703,4 @@ struct smp_resp { + }; + } __attribute__ ((packed)); + +-#else +-#error "Bitfield order not defined!" +-#endif +- + #endif /* _SAS_H_ */ +-- +2.43.0 + diff --git a/queue-5.15/scsi-usb-call-scsi_done-directly.patch b/queue-5.15/scsi-usb-call-scsi_done-directly.patch new file mode 100644 index 00000000000..781abf53e0b --- /dev/null +++ b/queue-5.15/scsi-usb-call-scsi_done-directly.patch @@ -0,0 +1,109 @@ +From cc631baf15a9076feee072bc122092536f908a4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Oct 2021 13:46:10 -0700 +Subject: scsi: usb: Call scsi_done() directly + +From: Bart Van Assche + +[ Upstream commit 46c97948e9b5bc8b67fd72741a2fe723ac1d14d7 ] + +Conditional statements are faster than indirect calls. Hence call +scsi_done() directly. + +Link: https://lore.kernel.org/r/20211007204618.2196847-10-bvanassche@acm.org +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Stable-dep-of: cd5432c71235 ("USB: UAS: return ENODEV when submit urbs fail with device not attached") +Signed-off-by: Sasha Levin +--- + drivers/usb/storage/scsiglue.c | 1 - + drivers/usb/storage/uas.c | 10 ++++------ + drivers/usb/storage/usb.c | 4 ++-- + 3 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c +index b8e1109f0e0d4..e104aa651ccc7 100644 +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -393,7 +393,6 @@ static int queuecommand_lck(struct scsi_cmnd *srb, + } + + /* enqueue the command and wake up the control thread */ +- srb->scsi_done = done; + us->srb = srb; + complete(&us->cmnd_ready); + +diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c +index bef89c6bd1d7f..774d18907f472 100644 +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -256,7 +256,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) + return -EBUSY; + devinfo->cmnd[cmdinfo->uas_tag - 1] = NULL; + uas_free_unsubmitted_urbs(cmnd); +- cmnd->scsi_done(cmnd); ++ scsi_done(cmnd); + return 0; + } + +@@ -653,7 +653,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + memcpy(cmnd->sense_buffer, usb_stor_sense_invalidCDB, + sizeof(usb_stor_sense_invalidCDB)); + cmnd->result = SAM_STAT_CHECK_CONDITION; +- cmnd->scsi_done(cmnd); ++ scsi_done(cmnd); + return 0; + } + +@@ -661,7 +661,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + + if (devinfo->resetting) { + set_host_byte(cmnd, DID_ERROR); +- cmnd->scsi_done(cmnd); ++ scsi_done(cmnd); + goto zombie; + } + +@@ -675,8 +675,6 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + return SCSI_MLQUEUE_DEVICE_BUSY; + } + +- cmnd->scsi_done = done; +- + memset(cmdinfo, 0, sizeof(*cmdinfo)); + cmdinfo->uas_tag = idx + 1; /* uas-tag == usb-stream-id, so 1 based */ + cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB; +@@ -706,7 +704,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + */ + if (err == -ENODEV) { + set_host_byte(cmnd, DID_ERROR); +- cmnd->scsi_done(cmnd); ++ scsi_done(cmnd); + goto zombie; + } + if (err) { +diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c +index 90aa9c12ffac5..8b543f2c98575 100644 +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -388,7 +388,7 @@ static int usb_stor_control_thread(void * __us) + if (srb->result == DID_ABORT << 16) { + SkipForAbort: + usb_stor_dbg(us, "scsi command aborted\n"); +- srb = NULL; /* Don't call srb->scsi_done() */ ++ srb = NULL; /* Don't call scsi_done() */ + } + + /* +@@ -417,7 +417,7 @@ static int usb_stor_control_thread(void * __us) + if (srb) { + usb_stor_dbg(us, "scsi cmd done, result=0x%x\n", + srb->result); +- srb->scsi_done(srb); ++ scsi_done(srb); + } + } /* for (;;) */ + +-- +2.43.0 + diff --git a/queue-5.15/scsi-usb-stop-using-the-scsi-pointer.patch b/queue-5.15/scsi-usb-stop-using-the-scsi-pointer.patch new file mode 100644 index 00000000000..02584ee6b4d --- /dev/null +++ b/queue-5.15/scsi-usb-stop-using-the-scsi-pointer.patch @@ -0,0 +1,216 @@ +From e1a7f7ad0f8ab0f0a661e8c175eaef6351f7cf48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Feb 2022 11:51:13 -0800 +Subject: scsi: usb: Stop using the SCSI pointer + +From: Bart Van Assche + +[ Upstream commit 5dfcf1ad933fe877cb44e9fb7a661dfc22190101 ] + +Set scsi_host_template.cmd_size instead of using the SCSI pointer for +storing driver-private data. Change the type of the argument of +uas_add_work() from struct uas_cmd_info * into struct scsi_cmnd * because +it is easier to convert a SCSI command pointer into a uas_cmd_info pointer +than the other way around. + +This patch prepares for removal of the SCSI pointer from struct scsi_cmnd. + +Link: https://lore.kernel.org/r/20220218195117.25689-46-bvanassche@acm.org +Cc: linux-usb@vger.kernel.org +Reviewed-by: Johannes Thumshirn +Reviewed-by: Hannes Reinecke +Reviewed-by: Himanshu Madhani +Acked-by: Greg Kroah-Hartman +Acked-by: Oliver Neukum +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Stable-dep-of: cd5432c71235 ("USB: UAS: return ENODEV when submit urbs fail with device not attached") +Signed-off-by: Sasha Levin +--- + drivers/usb/storage/uas.c | 43 ++++++++++++++++++--------------------- + 1 file changed, 20 insertions(+), 23 deletions(-) + +diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c +index 774d18907f472..d11a9481f6d00 100644 +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -113,7 +113,7 @@ static void uas_do_work(struct work_struct *work) + continue; + + cmnd = devinfo->cmnd[i]; +- cmdinfo = (void *)&cmnd->SCp; ++ cmdinfo = scsi_cmd_priv(cmnd); + + if (!(cmdinfo->state & IS_IN_WORK_LIST)) + continue; +@@ -139,10 +139,9 @@ static void uas_scan_work(struct work_struct *work) + dev_dbg(&devinfo->intf->dev, "scan complete\n"); + } + +-static void uas_add_work(struct uas_cmd_info *cmdinfo) ++static void uas_add_work(struct scsi_cmnd *cmnd) + { +- struct scsi_pointer *scp = (void *)cmdinfo; +- struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp); ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct uas_dev_info *devinfo = cmnd->device->hostdata; + + lockdep_assert_held(&devinfo->lock); +@@ -163,7 +162,7 @@ static void uas_zap_pending(struct uas_dev_info *devinfo, int result) + continue; + + cmnd = devinfo->cmnd[i]; +- cmdinfo = (void *)&cmnd->SCp; ++ cmdinfo = scsi_cmd_priv(cmnd); + uas_log_cmd_state(cmnd, __func__, 0); + /* Sense urbs were killed, clear COMMAND_INFLIGHT manually */ + cmdinfo->state &= ~COMMAND_INFLIGHT; +@@ -200,15 +199,14 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) + static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix, + int status) + { +- struct uas_cmd_info *ci = (void *)&cmnd->SCp; +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *ci = scsi_cmd_priv(cmnd); + + if (status == -ENODEV) /* too late */ + return; + + scmd_printk(KERN_INFO, cmnd, + "%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ", +- prefix, status, cmdinfo->uas_tag, ++ prefix, status, ci->uas_tag, + (ci->state & SUBMIT_STATUS_URB) ? " s-st" : "", + (ci->state & ALLOC_DATA_IN_URB) ? " a-in" : "", + (ci->state & SUBMIT_DATA_IN_URB) ? " s-in" : "", +@@ -231,7 +229,7 @@ static void uas_free_unsubmitted_urbs(struct scsi_cmnd *cmnd) + if (!cmnd) + return; + +- cmdinfo = (void *)&cmnd->SCp; ++ cmdinfo = scsi_cmd_priv(cmnd); + + if (cmdinfo->state & SUBMIT_CMD_URB) + usb_free_urb(cmdinfo->cmd_urb); +@@ -245,7 +243,7 @@ static void uas_free_unsubmitted_urbs(struct scsi_cmnd *cmnd) + + static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) + { +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; + + lockdep_assert_held(&devinfo->lock); +@@ -263,13 +261,13 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) + static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, + unsigned direction) + { +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + int err; + + cmdinfo->state |= direction | SUBMIT_STATUS_URB; + err = uas_submit_urbs(cmnd, cmnd->device->hostdata); + if (err) { +- uas_add_work(cmdinfo); ++ uas_add_work(cmnd); + } + } + +@@ -329,7 +327,7 @@ static void uas_stat_cmplt(struct urb *urb) + } + + cmnd = devinfo->cmnd[idx]; +- cmdinfo = (void *)&cmnd->SCp; ++ cmdinfo = scsi_cmd_priv(cmnd); + + if (!(cmdinfo->state & COMMAND_INFLIGHT)) { + uas_log_cmd_state(cmnd, "unexpected status cmplt", 0); +@@ -394,7 +392,7 @@ static void uas_stat_cmplt(struct urb *urb) + static void uas_data_cmplt(struct urb *urb) + { + struct scsi_cmnd *cmnd = urb->context; +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; + struct scsi_data_buffer *sdb = &cmnd->sdb; + unsigned long flags; +@@ -446,7 +444,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, + enum dma_data_direction dir) + { + struct usb_device *udev = devinfo->udev; +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct urb *urb = usb_alloc_urb(0, gfp); + struct scsi_data_buffer *sdb = &cmnd->sdb; + unsigned int pipe = (dir == DMA_FROM_DEVICE) +@@ -468,7 +466,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, + struct scsi_cmnd *cmnd) + { + struct usb_device *udev = devinfo->udev; +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct urb *urb = usb_alloc_urb(0, gfp); + struct sense_iu *iu; + +@@ -496,7 +494,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, + { + struct usb_device *udev = devinfo->udev; + struct scsi_device *sdev = cmnd->device; +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct urb *urb = usb_alloc_urb(0, gfp); + struct command_iu *iu; + int len; +@@ -558,7 +556,7 @@ static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd, gfp_t gfp) + static int uas_submit_urbs(struct scsi_cmnd *cmnd, + struct uas_dev_info *devinfo) + { +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct urb *urb; + int err; + +@@ -638,12 +636,10 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + { + struct scsi_device *sdev = cmnd->device; + struct uas_dev_info *devinfo = sdev->hostdata; +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + unsigned long flags; + int idx, err; + +- BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); +- + /* Re-check scsi_block_requests now that we've the host-lock */ + if (cmnd->device->host->host_self_blocked) + return SCSI_MLQUEUE_DEVICE_BUSY; +@@ -713,7 +709,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + spin_unlock_irqrestore(&devinfo->lock, flags); + return SCSI_MLQUEUE_DEVICE_BUSY; + } +- uas_add_work(cmdinfo); ++ uas_add_work(cmnd); + } + + devinfo->cmnd[idx] = cmnd; +@@ -731,7 +727,7 @@ static DEF_SCSI_QCMD(uas_queuecommand) + */ + static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) + { +- struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; ++ struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); + struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata; + struct urb *data_in_urb = NULL; + struct urb *data_out_urb = NULL; +@@ -911,6 +907,7 @@ static struct scsi_host_template uas_host_template = { + .this_id = -1, + .skip_settle_delay = 1, + .dma_boundary = PAGE_SIZE - 1, ++ .cmd_size = sizeof(struct uas_cmd_info), + }; + + #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ +-- +2.43.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 63fb3b060c0..28a58845ed8 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -603,3 +603,21 @@ x86-cpu-enable-stibp-on-amd-if-automatic-ibrs-is-enabled.patch pci-dpc-quirk-pio-log-size-for-intel-ice-lake-root-ports.patch scsi-lpfc-correct-size-for-wqe-for-memset.patch usb-core-fix-deadlock-in-usb_deauthorize_interface.patch +scsi-usb-call-scsi_done-directly.patch +scsi-usb-stop-using-the-scsi-pointer.patch +usb-uas-return-enodev-when-submit-urbs-fail-with-dev.patch +scsi-libsas-introduce-struct-smp_disc_resp.patch +scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch +scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch +nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch +mlxbf_gige-stop-phy-during-open-error-paths.patch +iwlwifi-mvm-rfi-use-kmemdup-to-replace-kzalloc-memcp.patch +wifi-iwlwifi-mvm-rfi-fix-potential-response-leaks.patch +ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch +s390-qeth-handle-deferred-cc1.patch +tcp-properly-terminate-timers-for-kernel-sockets.patch +acpica-debugger-check-status-of-acpi_evaluate_object.patch +mlxbf_gige-call-request_irq-after-napi-initialized.patch +bpf-protect-against-int-overflow-for-stack-access-si.patch +octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch +dm-integrity-fix-out-of-range-warning.patch diff --git a/queue-5.15/tcp-properly-terminate-timers-for-kernel-sockets.patch b/queue-5.15/tcp-properly-terminate-timers-for-kernel-sockets.patch new file mode 100644 index 00000000000..58965b9be60 --- /dev/null +++ b/queue-5.15/tcp-properly-terminate-timers-for-kernel-sockets.patch @@ -0,0 +1,138 @@ +From 08155e4b5d9ce4f7e304e507529a0d9a5b5da285 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Mar 2024 13:57:32 +0000 +Subject: tcp: properly terminate timers for kernel sockets + +From: Eric Dumazet + +[ Upstream commit 151c9c724d05d5b0dd8acd3e11cb69ef1f2dbada ] + +We had various syzbot reports about tcp timers firing after +the corresponding netns has been dismantled. + +Fortunately Josef Bacik could trigger the issue more often, +and could test a patch I wrote two years ago. + +When TCP sockets are closed, we call inet_csk_clear_xmit_timers() +to 'stop' the timers. + +inet_csk_clear_xmit_timers() can be called from any context, +including when socket lock is held. +This is the reason it uses sk_stop_timer(), aka del_timer(). +This means that ongoing timers might finish much later. + +For user sockets, this is fine because each running timer +holds a reference on the socket, and the user socket holds +a reference on the netns. + +For kernel sockets, we risk that the netns is freed before +timer can complete, because kernel sockets do not hold +reference on the netns. + +This patch adds inet_csk_clear_xmit_timers_sync() function +that using sk_stop_timer_sync() to make sure all timers +are terminated before the kernel socket is released. +Modules using kernel sockets close them in their netns exit() +handler. + +Also add sock_not_owned_by_me() helper to get LOCKDEP +support : inet_csk_clear_xmit_timers_sync() must not be called +while socket lock is held. + +It is very possible we can revert in the future commit +3a58f13a881e ("net: rds: acquire refcount on TCP sockets") +which attempted to solve the issue in rds only. +(net/smc/af_smc.c and net/mptcp/subflow.c have similar code) + +We probably can remove the check_net() tests from +tcp_out_of_resources() and __tcp_close() in the future. + +Reported-by: Josef Bacik +Closes: https://lore.kernel.org/netdev/20240314210740.GA2823176@perftesting/ +Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.") +Fixes: 8a68173691f0 ("net: sk_clone_lock() should only do get_net() if the parent is not a kernel socket") +Link: https://lore.kernel.org/bpf/CANn89i+484ffqb93aQm1N-tjxxvb3WDKX0EbD7318RwRgsatjw@mail.gmail.com/ +Signed-off-by: Eric Dumazet +Tested-by: Josef Bacik +Cc: Tetsuo Handa +Link: https://lore.kernel.org/r/20240322135732.1535772-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/inet_connection_sock.h | 1 + + include/net/sock.h | 7 +++++++ + net/ipv4/inet_connection_sock.c | 14 ++++++++++++++ + net/ipv4/tcp.c | 2 ++ + 4 files changed, 24 insertions(+) + +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index 798aad21694e2..b6b7e210f9d7a 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -169,6 +169,7 @@ void inet_csk_init_xmit_timers(struct sock *sk, + void (*delack_handler)(struct timer_list *), + void (*keepalive_handler)(struct timer_list *)); + void inet_csk_clear_xmit_timers(struct sock *sk); ++void inet_csk_clear_xmit_timers_sync(struct sock *sk); + + static inline void inet_csk_schedule_ack(struct sock *sk) + { +diff --git a/include/net/sock.h b/include/net/sock.h +index e19eebaf59f73..44ebec3fdda64 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1751,6 +1751,13 @@ static inline void sock_owned_by_me(const struct sock *sk) + #endif + } + ++static inline void sock_not_owned_by_me(const struct sock *sk) ++{ ++#ifdef CONFIG_LOCKDEP ++ WARN_ON_ONCE(lockdep_sock_is_held(sk) && debug_locks); ++#endif ++} ++ + static inline bool sock_owned_by_user(const struct sock *sk) + { + sock_owned_by_me(sk); +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index da43957a58438..27975a44d1f9d 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -589,6 +589,20 @@ void inet_csk_clear_xmit_timers(struct sock *sk) + } + EXPORT_SYMBOL(inet_csk_clear_xmit_timers); + ++void inet_csk_clear_xmit_timers_sync(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ ++ /* ongoing timer handlers need to acquire socket lock. */ ++ sock_not_owned_by_me(sk); ++ ++ icsk->icsk_pending = icsk->icsk_ack.pending = 0; ++ ++ sk_stop_timer_sync(sk, &icsk->icsk_retransmit_timer); ++ sk_stop_timer_sync(sk, &icsk->icsk_delack_timer); ++ sk_stop_timer_sync(sk, &sk->sk_timer); ++} ++ + void inet_csk_delete_keepalive_timer(struct sock *sk) + { + sk_stop_timer(sk, &sk->sk_timer); +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 521c15962c719..16fd3da68e9f6 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2916,6 +2916,8 @@ void tcp_close(struct sock *sk, long timeout) + lock_sock(sk); + __tcp_close(sk, timeout); + release_sock(sk); ++ if (!sk->sk_net_refcnt) ++ inet_csk_clear_xmit_timers_sync(sk); + sock_put(sk); + } + EXPORT_SYMBOL(tcp_close); +-- +2.43.0 + diff --git a/queue-5.15/usb-uas-return-enodev-when-submit-urbs-fail-with-dev.patch b/queue-5.15/usb-uas-return-enodev-when-submit-urbs-fail-with-dev.patch new file mode 100644 index 00000000000..6f0fd863d60 --- /dev/null +++ b/queue-5.15/usb-uas-return-enodev-when-submit-urbs-fail-with-dev.patch @@ -0,0 +1,154 @@ +From 9def5cbfe2a59ab83b1a1f56d6d2278e86a7ff6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 02:08:14 +0800 +Subject: USB: UAS: return ENODEV when submit urbs fail with device not + attached + +From: Weitao Wang + +[ Upstream commit cd5432c712351a3d5f82512908f5febfca946ca6 ] + +In the scenario of entering hibernation with udisk in the system, if the +udisk was gone or resume fail in the thaw phase of hibernation. Its state +will be set to NOTATTACHED. At this point, usb_hub_wq was already freezed +and can't not handle disconnect event. Next, in the poweroff phase of +hibernation, SYNCHRONIZE_CACHE SCSI command will be sent to this udisk +when poweroff this scsi device, which will cause uas_submit_urbs to be +called to submit URB for sense/data/cmd pipe. However, these URBs will +submit fail as device was set to NOTATTACHED state. Then, uas_submit_urbs +will return a value SCSI_MLQUEUE_DEVICE_BUSY to the caller. That will lead +the SCSI layer go into an ugly loop and system fail to go into hibernation. + +On the other hand, when we specially check for -ENODEV in function +uas_queuecommand_lck, returning DID_ERROR to SCSI layer will cause device +poweroff fail and system shutdown instead of entering hibernation. + +To fix this issue, let uas_submit_urbs to return original generic error +when submitting URB failed. At the same time, we need to translate -ENODEV +to DID_NOT_CONNECT for the SCSI layer. + +Suggested-by: Oliver Neukum +Cc: stable@vger.kernel.org +Signed-off-by: Weitao Wang +Link: https://lore.kernel.org/r/20240306180814.4897-1-WeitaoWang-oc@zhaoxin.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/storage/uas.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c +index d11a9481f6d00..11a551a9cd057 100644 +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -533,7 +533,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, + * daft to me. + */ + +-static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd, gfp_t gfp) ++static int uas_submit_sense_urb(struct scsi_cmnd *cmnd, gfp_t gfp) + { + struct uas_dev_info *devinfo = cmnd->device->hostdata; + struct urb *urb; +@@ -541,30 +541,28 @@ static struct urb *uas_submit_sense_urb(struct scsi_cmnd *cmnd, gfp_t gfp) + + urb = uas_alloc_sense_urb(devinfo, gfp, cmnd); + if (!urb) +- return NULL; ++ return -ENOMEM; + usb_anchor_urb(urb, &devinfo->sense_urbs); + err = usb_submit_urb(urb, gfp); + if (err) { + usb_unanchor_urb(urb); + uas_log_cmd_state(cmnd, "sense submit err", err); + usb_free_urb(urb); +- return NULL; + } +- return urb; ++ return err; + } + + static int uas_submit_urbs(struct scsi_cmnd *cmnd, + struct uas_dev_info *devinfo) + { + struct uas_cmd_info *cmdinfo = scsi_cmd_priv(cmnd); +- struct urb *urb; + int err; + + lockdep_assert_held(&devinfo->lock); + if (cmdinfo->state & SUBMIT_STATUS_URB) { +- urb = uas_submit_sense_urb(cmnd, GFP_ATOMIC); +- if (!urb) +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ err = uas_submit_sense_urb(cmnd, GFP_ATOMIC); ++ if (err) ++ return err; + cmdinfo->state &= ~SUBMIT_STATUS_URB; + } + +@@ -572,7 +570,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, + cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, GFP_ATOMIC, + cmnd, DMA_FROM_DEVICE); + if (!cmdinfo->data_in_urb) +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ return -ENOMEM; + cmdinfo->state &= ~ALLOC_DATA_IN_URB; + } + +@@ -582,7 +580,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, + if (err) { + usb_unanchor_urb(cmdinfo->data_in_urb); + uas_log_cmd_state(cmnd, "data in submit err", err); +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ return err; + } + cmdinfo->state &= ~SUBMIT_DATA_IN_URB; + cmdinfo->state |= DATA_IN_URB_INFLIGHT; +@@ -592,7 +590,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, + cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, GFP_ATOMIC, + cmnd, DMA_TO_DEVICE); + if (!cmdinfo->data_out_urb) +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ return -ENOMEM; + cmdinfo->state &= ~ALLOC_DATA_OUT_URB; + } + +@@ -602,7 +600,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, + if (err) { + usb_unanchor_urb(cmdinfo->data_out_urb); + uas_log_cmd_state(cmnd, "data out submit err", err); +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ return err; + } + cmdinfo->state &= ~SUBMIT_DATA_OUT_URB; + cmdinfo->state |= DATA_OUT_URB_INFLIGHT; +@@ -611,7 +609,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, + if (cmdinfo->state & ALLOC_CMD_URB) { + cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, GFP_ATOMIC, cmnd); + if (!cmdinfo->cmd_urb) +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ return -ENOMEM; + cmdinfo->state &= ~ALLOC_CMD_URB; + } + +@@ -621,7 +619,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, + if (err) { + usb_unanchor_urb(cmdinfo->cmd_urb); + uas_log_cmd_state(cmnd, "cmd submit err", err); +- return SCSI_MLQUEUE_DEVICE_BUSY; ++ return err; + } + cmdinfo->cmd_urb = NULL; + cmdinfo->state &= ~SUBMIT_CMD_URB; +@@ -699,7 +697,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, + * of queueing, no matter how fatal the error + */ + if (err == -ENODEV) { +- set_host_byte(cmnd, DID_ERROR); ++ set_host_byte(cmnd, DID_NO_CONNECT); + scsi_done(cmnd); + goto zombie; + } +-- +2.43.0 + diff --git a/queue-5.15/wifi-iwlwifi-mvm-rfi-fix-potential-response-leaks.patch b/queue-5.15/wifi-iwlwifi-mvm-rfi-fix-potential-response-leaks.patch new file mode 100644 index 00000000000..c485fbccdac --- /dev/null +++ b/queue-5.15/wifi-iwlwifi-mvm-rfi-fix-potential-response-leaks.patch @@ -0,0 +1,50 @@ +From 445b4b00512270d5ff3c05a840336af35222e431 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Mar 2024 10:10:17 +0200 +Subject: wifi: iwlwifi: mvm: rfi: fix potential response leaks + +From: Johannes Berg + +[ Upstream commit 06a093807eb7b5c5b29b6cff49f8174a4e702341 ] + +If the rx payload length check fails, or if kmemdup() fails, +we still need to free the command response. Fix that. + +Fixes: 21254908cbe9 ("iwlwifi: mvm: add RFI-M support") +Co-authored-by: Anjaneyulu +Signed-off-by: Johannes Berg +Signed-off-by: Miri Korenblit +Link: https://msgid.link/20240319100755.db2fa0196aa7.I116293b132502ac68a65527330fa37799694b79c@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/rfi.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c +index 1954b4cdb90b4..4deb242df7b37 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c +@@ -104,13 +104,17 @@ struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm) + if (ret) + return ERR_PTR(ret); + +- if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) != resp_size)) ++ if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) != ++ resp_size)) { ++ iwl_free_resp(&cmd); + return ERR_PTR(-EIO); ++ } + + resp = kmemdup(cmd.resp_pkt->data, resp_size, GFP_KERNEL); ++ iwl_free_resp(&cmd); ++ + if (!resp) + return ERR_PTR(-ENOMEM); + +- iwl_free_resp(&cmd); + return resp; + } +-- +2.43.0 + -- 2.47.2