From: Sasha Levin Date: Sat, 31 Aug 2024 23:13:48 +0000 (-0400) Subject: Fixes for 6.10 X-Git-Tag: v4.19.321~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8071a60f3060a199a02dfe26036603a0c94750d6;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.10 Signed-off-by: Sasha Levin --- diff --git a/queue-6.10/bluetooth-btnxpuart-fix-random-crash-seen-while-remo.patch b/queue-6.10/bluetooth-btnxpuart-fix-random-crash-seen-while-remo.patch new file mode 100644 index 00000000000..887559ac1f3 --- /dev/null +++ b/queue-6.10/bluetooth-btnxpuart-fix-random-crash-seen-while-remo.patch @@ -0,0 +1,126 @@ +From fb7751a443dc796c927e5f3cf9cd8f35177f1810 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Aug 2024 15:51:13 +0530 +Subject: Bluetooth: btnxpuart: Fix random crash seen while removing driver + +From: Neeraj Sanjay Kale + +[ Upstream commit 35237475384ab3622f63c3c09bdf6af6dacfe9c3 ] + +This fixes the random kernel crash seen while removing the driver, when +running the load/unload test over multiple iterations. + +1) modprobe btnxpuart +2) hciconfig hci0 reset +3) hciconfig (check hci0 interface up with valid BD address) +4) modprobe -r btnxpuart +Repeat steps 1 to 4 + +The ps_wakeup() call in btnxpuart_close() schedules the psdata->work(), +which gets scheduled after module is removed, causing a kernel crash. + +This hidden issue got highlighted after enabling Power Save by default +in 4183a7be7700 (Bluetooth: btnxpuart: Enable Power Save feature on +startup) + +The new ps_cleanup() deasserts UART break immediately while closing +serdev device, cancels any scheduled ps_work and destroys the ps_lock +mutex. + +[ 85.884604] Unable to handle kernel paging request at virtual address ffffd4a61638f258 +[ 85.884624] Mem abort info: +[ 85.884625] ESR = 0x0000000086000007 +[ 85.884628] EC = 0x21: IABT (current EL), IL = 32 bits +[ 85.884633] SET = 0, FnV = 0 +[ 85.884636] EA = 0, S1PTW = 0 +[ 85.884638] FSC = 0x07: level 3 translation fault +[ 85.884642] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041dd0000 +[ 85.884646] [ffffd4a61638f258] pgd=1000000095fff003, p4d=1000000095fff003, pud=100000004823d003, pmd=100000004823e003, pte=0000000000000000 +[ 85.884662] Internal error: Oops: 0000000086000007 [#1] PREEMPT SMP +[ 85.890932] Modules linked in: algif_hash algif_skcipher af_alg overlay fsl_jr_uio caam_jr caamkeyblob_desc caamhash_desc caamalg_desc crypto_engine authenc libdes crct10dif_ce polyval_ce polyval_generic snd_soc_imx_spdif snd_soc_imx_card snd_soc_ak5558 snd_soc_ak4458 caam secvio error snd_soc_fsl_spdif snd_soc_fsl_micfil snd_soc_fsl_sai snd_soc_fsl_utils gpio_ir_recv rc_core fuse [last unloaded: btnxpuart(O)] +[ 85.927297] CPU: 1 PID: 67 Comm: kworker/1:3 Tainted: G O 6.1.36+g937b1be4345a #1 +[ 85.936176] Hardware name: FSL i.MX8MM EVK board (DT) +[ 85.936182] Workqueue: events 0xffffd4a61638f380 +[ 85.936198] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 85.952817] pc : 0xffffd4a61638f258 +[ 85.952823] lr : 0xffffd4a61638f258 +[ 85.952827] sp : ffff8000084fbd70 +[ 85.952829] x29: ffff8000084fbd70 x28: 0000000000000000 x27: 0000000000000000 +[ 85.963112] x26: ffffd4a69133f000 x25: ffff4bf1c8540990 x24: ffff4bf215b87305 +[ 85.963119] x23: ffff4bf215b87300 x22: ffff4bf1c85409d0 x21: ffff4bf1c8540970 +[ 85.977382] x20: 0000000000000000 x19: ffff4bf1c8540880 x18: 0000000000000000 +[ 85.977391] x17: 0000000000000000 x16: 0000000000000133 x15: 0000ffffe2217090 +[ 85.977399] x14: 0000000000000001 x13: 0000000000000133 x12: 0000000000000139 +[ 85.977407] x11: 0000000000000001 x10: 0000000000000a60 x9 : ffff8000084fbc50 +[ 85.977417] x8 : ffff4bf215b7d000 x7 : ffff4bf215b83b40 x6 : 00000000000003e8 +[ 85.977424] x5 : 00000000410fd030 x4 : 0000000000000000 x3 : 0000000000000000 +[ 85.977432] x2 : 0000000000000000 x1 : ffff4bf1c4265880 x0 : 0000000000000000 +[ 85.977443] Call trace: +[ 85.977446] 0xffffd4a61638f258 +[ 85.977451] 0xffffd4a61638f3e8 +[ 85.977455] process_one_work+0x1d4/0x330 +[ 85.977464] worker_thread+0x6c/0x430 +[ 85.977471] kthread+0x108/0x10c +[ 85.977476] ret_from_fork+0x10/0x20 +[ 85.977488] Code: bad PC value +[ 85.977491] ---[ end trace 0000000000000000 ]--- + +Preset since v6.9.11 +Fixes: 86d55f124b52 ("Bluetooth: btnxpuart: Deasset UART break before closing serdev device") +Signed-off-by: Neeraj Sanjay Kale +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btnxpuart.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index 1bb97747c4836..eeba2d26d1cb9 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -438,6 +438,23 @@ static bool ps_wakeup(struct btnxpuart_dev *nxpdev) + return false; + } + ++static void ps_cleanup(struct btnxpuart_dev *nxpdev) ++{ ++ struct ps_data *psdata = &nxpdev->psdata; ++ u8 ps_state; ++ ++ mutex_lock(&psdata->ps_lock); ++ ps_state = psdata->ps_state; ++ mutex_unlock(&psdata->ps_lock); ++ ++ if (ps_state != PS_STATE_AWAKE) ++ ps_control(psdata->hdev, PS_STATE_AWAKE); ++ ++ ps_cancel_timer(nxpdev); ++ cancel_work_sync(&psdata->work); ++ mutex_destroy(&psdata->ps_lock); ++} ++ + static int send_ps_cmd(struct hci_dev *hdev, void *data) + { + struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); +@@ -1307,7 +1324,6 @@ static int btnxpuart_close(struct hci_dev *hdev) + { + struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); + +- ps_wakeup(nxpdev); + serdev_device_close(nxpdev->serdev); + skb_queue_purge(&nxpdev->txq); + kfree_skb(nxpdev->rx_skb); +@@ -1456,8 +1472,8 @@ static void nxp_serdev_remove(struct serdev_device *serdev) + nxpdev->new_baudrate = nxpdev->fw_init_baudrate; + nxp_set_baudrate_cmd(hdev, NULL); + } +- ps_cancel_timer(nxpdev); + } ++ ps_cleanup(nxpdev); + hci_unregister_dev(hdev); + hci_free_dev(hdev); + } +-- +2.43.0 + diff --git a/queue-6.10/bluetooth-btnxpuart-handle-fw-download-abort-scenari.patch b/queue-6.10/bluetooth-btnxpuart-handle-fw-download-abort-scenari.patch new file mode 100644 index 00000000000..3e0a0ad1ef8 --- /dev/null +++ b/queue-6.10/bluetooth-btnxpuart-handle-fw-download-abort-scenari.patch @@ -0,0 +1,131 @@ +From a907b35bcc1d6505e4a8418e3850e27091d12b9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 May 2024 12:36:57 +0530 +Subject: Bluetooth: btnxpuart: Handle FW Download Abort scenario + +From: Neeraj Sanjay Kale + +[ Upstream commit e3c4891098c875a63ab0c3b31d584f6d4f1895fd ] + +This adds a new flag BTNXPUART_FW_DOWNLOAD_ABORT which handles the +situation where driver is removed while firmware download is in +progress. + +logs: +modprobe btnxpuart +[65239.230431] Bluetooth: hci0: ChipID: 7601, Version: 0 +[65239.236670] Bluetooth: hci0: Request Firmware: nxp/uartspi_n61x_v1.bin.se +rmmod btnxpuart +[65241.425300] Bluetooth: hci0: FW Download Aborted + +Signed-off-by: Neeraj Sanjay Kale +Tested-by: Guillaume Legoupil +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: 35237475384a ("Bluetooth: btnxpuart: Fix random crash seen while removing driver") +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btnxpuart.c | 47 ++++++++++++++++++++++++----------- + 1 file changed, 33 insertions(+), 14 deletions(-) + +diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c +index d310b525fbf00..1bb97747c4836 100644 +--- a/drivers/bluetooth/btnxpuart.c ++++ b/drivers/bluetooth/btnxpuart.c +@@ -29,6 +29,7 @@ + #define BTNXPUART_CHECK_BOOT_SIGNATURE 3 + #define BTNXPUART_SERDEV_OPEN 4 + #define BTNXPUART_IR_IN_PROGRESS 5 ++#define BTNXPUART_FW_DOWNLOAD_ABORT 6 + + /* NXP HW err codes */ + #define BTNXPUART_IR_HW_ERR 0xb0 +@@ -159,6 +160,7 @@ struct btnxpuart_dev { + u8 fw_name[MAX_FW_FILE_NAME_LEN]; + u32 fw_dnld_v1_offset; + u32 fw_v1_sent_bytes; ++ u32 fw_dnld_v3_offset; + u32 fw_v3_offset_correction; + u32 fw_v1_expected_len; + u32 boot_reg_offset; +@@ -566,6 +568,7 @@ static int nxp_download_firmware(struct hci_dev *hdev) + nxpdev->fw_v1_sent_bytes = 0; + nxpdev->fw_v1_expected_len = HDR_LEN; + nxpdev->boot_reg_offset = 0; ++ nxpdev->fw_dnld_v3_offset = 0; + nxpdev->fw_v3_offset_correction = 0; + nxpdev->baudrate_changed = false; + nxpdev->timeout_changed = false; +@@ -580,14 +583,23 @@ static int nxp_download_firmware(struct hci_dev *hdev) + !test_bit(BTNXPUART_FW_DOWNLOADING, + &nxpdev->tx_state), + msecs_to_jiffies(60000)); ++ ++ release_firmware(nxpdev->fw); ++ memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name)); ++ + if (err == 0) { +- bt_dev_err(hdev, "FW Download Timeout."); ++ bt_dev_err(hdev, "FW Download Timeout. offset: %d", ++ nxpdev->fw_dnld_v1_offset ? ++ nxpdev->fw_dnld_v1_offset : ++ nxpdev->fw_dnld_v3_offset); + return -ETIMEDOUT; + } ++ if (test_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state)) { ++ bt_dev_err(hdev, "FW Download Aborted"); ++ return -EINTR; ++ } + + serdev_device_set_flow_control(nxpdev->serdev, true); +- release_firmware(nxpdev->fw); +- memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name)); + + /* Allow the downloaded FW to initialize */ + msleep(1200); +@@ -998,8 +1010,9 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb) + goto free_skb; + } + +- serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data + offset - +- nxpdev->fw_v3_offset_correction, len); ++ nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction; ++ serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data + ++ nxpdev->fw_dnld_v3_offset, len); + + free_skb: + kfree_skb(skb); +@@ -1429,16 +1442,22 @@ static void nxp_serdev_remove(struct serdev_device *serdev) + struct btnxpuart_dev *nxpdev = serdev_device_get_drvdata(serdev); + struct hci_dev *hdev = nxpdev->hdev; + +- /* Restore FW baudrate to fw_init_baudrate if changed. +- * This will ensure FW baudrate is in sync with +- * driver baudrate in case this driver is re-inserted. +- */ +- if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) { +- nxpdev->new_baudrate = nxpdev->fw_init_baudrate; +- nxp_set_baudrate_cmd(hdev, NULL); ++ if (is_fw_downloading(nxpdev)) { ++ set_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state); ++ clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); ++ wake_up_interruptible(&nxpdev->check_boot_sign_wait_q); ++ wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q); ++ } else { ++ /* Restore FW baudrate to fw_init_baudrate if changed. ++ * This will ensure FW baudrate is in sync with ++ * driver baudrate in case this driver is re-inserted. ++ */ ++ if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) { ++ nxpdev->new_baudrate = nxpdev->fw_init_baudrate; ++ nxp_set_baudrate_cmd(hdev, NULL); ++ } ++ ps_cancel_timer(nxpdev); + } +- +- ps_cancel_timer(nxpdev); + hci_unregister_dev(hdev); + hci_free_dev(hdev); + } +-- +2.43.0 + diff --git a/queue-6.10/bluetooth-hci_core-fix-not-handling-hibernation-acti.patch b/queue-6.10/bluetooth-hci_core-fix-not-handling-hibernation-acti.patch new file mode 100644 index 00000000000..84206c34c6c --- /dev/null +++ b/queue-6.10/bluetooth-hci_core-fix-not-handling-hibernation-acti.patch @@ -0,0 +1,45 @@ +From 1b55695f72768f74842b443770ac637513dbf440 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 14:41:52 -0400 +Subject: Bluetooth: hci_core: Fix not handling hibernation actions + +From: Luiz Augusto von Dentz + +[ Upstream commit 18b3256db76bd1130965acd99fbd38f87c3e6950 ] + +This fixes not handling hibernation actions on suspend notifier so they +are treated in the same way as regular suspend actions. + +Fixes: 9952d90ea288 ("Bluetooth: Handle PM_SUSPEND_PREPARE and PM_POST_SUSPEND") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_core.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index b488d0742c966..9493966cf389f 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -2431,10 +2431,16 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, + /* To avoid a potential race with hci_unregister_dev. */ + hci_dev_hold(hdev); + +- if (action == PM_SUSPEND_PREPARE) ++ switch (action) { ++ case PM_HIBERNATION_PREPARE: ++ case PM_SUSPEND_PREPARE: + ret = hci_suspend_dev(hdev); +- else if (action == PM_POST_SUSPEND) ++ break; ++ case PM_POST_HIBERNATION: ++ case PM_POST_SUSPEND: + ret = hci_resume_dev(hdev); ++ break; ++ } + + if (ret) + bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", +-- +2.43.0 + diff --git a/queue-6.10/bonding-change-ipsec_lock-from-spin-lock-to-mutex.patch b/queue-6.10/bonding-change-ipsec_lock-from-spin-lock-to-mutex.patch new file mode 100644 index 00000000000..072abab9ef9 --- /dev/null +++ b/queue-6.10/bonding-change-ipsec_lock-from-spin-lock-to-mutex.patch @@ -0,0 +1,296 @@ +From bb48f0b18cf738ed0275356cb2b35d0ac114cde8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 06:10:56 +0300 +Subject: bonding: change ipsec_lock from spin lock to mutex + +From: Jianbo Liu + +[ Upstream commit 2aeeef906d5a526dc60cf4af92eda69836c39b1f ] + +In the cited commit, bond->ipsec_lock is added to protect ipsec_list, +hence xdo_dev_state_add and xdo_dev_state_delete are called inside +this lock. As ipsec_lock is a spin lock and such xfrmdev ops may sleep, +"scheduling while atomic" will be triggered when changing bond's +active slave. + +[ 101.055189] BUG: scheduling while atomic: bash/902/0x00000200 +[ 101.055726] Modules linked in: +[ 101.058211] CPU: 3 PID: 902 Comm: bash Not tainted 6.9.0-rc4+ #1 +[ 101.058760] Hardware name: +[ 101.059434] Call Trace: +[ 101.059436] +[ 101.060873] dump_stack_lvl+0x51/0x60 +[ 101.061275] __schedule_bug+0x4e/0x60 +[ 101.061682] __schedule+0x612/0x7c0 +[ 101.062078] ? __mod_timer+0x25c/0x370 +[ 101.062486] schedule+0x25/0xd0 +[ 101.062845] schedule_timeout+0x77/0xf0 +[ 101.063265] ? asm_common_interrupt+0x22/0x40 +[ 101.063724] ? __bpf_trace_itimer_state+0x10/0x10 +[ 101.064215] __wait_for_common+0x87/0x190 +[ 101.064648] ? usleep_range_state+0x90/0x90 +[ 101.065091] cmd_exec+0x437/0xb20 [mlx5_core] +[ 101.065569] mlx5_cmd_do+0x1e/0x40 [mlx5_core] +[ 101.066051] mlx5_cmd_exec+0x18/0x30 [mlx5_core] +[ 101.066552] mlx5_crypto_create_dek_key+0xea/0x120 [mlx5_core] +[ 101.067163] ? bonding_sysfs_store_option+0x4d/0x80 [bonding] +[ 101.067738] ? kmalloc_trace+0x4d/0x350 +[ 101.068156] mlx5_ipsec_create_sa_ctx+0x33/0x100 [mlx5_core] +[ 101.068747] mlx5e_xfrm_add_state+0x47b/0xaa0 [mlx5_core] +[ 101.069312] bond_change_active_slave+0x392/0x900 [bonding] +[ 101.069868] bond_option_active_slave_set+0x1c2/0x240 [bonding] +[ 101.070454] __bond_opt_set+0xa6/0x430 [bonding] +[ 101.070935] __bond_opt_set_notify+0x2f/0x90 [bonding] +[ 101.071453] bond_opt_tryset_rtnl+0x72/0xb0 [bonding] +[ 101.071965] bonding_sysfs_store_option+0x4d/0x80 [bonding] +[ 101.072567] kernfs_fop_write_iter+0x10c/0x1a0 +[ 101.073033] vfs_write+0x2d8/0x400 +[ 101.073416] ? alloc_fd+0x48/0x180 +[ 101.073798] ksys_write+0x5f/0xe0 +[ 101.074175] do_syscall_64+0x52/0x110 +[ 101.074576] entry_SYSCALL_64_after_hwframe+0x4b/0x53 + +As bond_ipsec_add_sa_all and bond_ipsec_del_sa_all are only called +from bond_change_active_slave, which requires holding the RTNL lock. +And bond_ipsec_add_sa and bond_ipsec_del_sa are xfrm state +xdo_dev_state_add and xdo_dev_state_delete APIs, which are in user +context. So ipsec_lock doesn't have to be spin lock, change it to +mutex, and thus the above issue can be resolved. + +Fixes: 9a5605505d9c ("bonding: Add struct bond_ipesc to manage SA") +Signed-off-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Hangbin Liu +Acked-by: Jay Vosburgh +Link: https://patch.msgid.link/20240823031056.110999-4-jianbol@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 79 ++++++++++++++++++--------------- + include/net/bonding.h | 2 +- + 2 files changed, 44 insertions(+), 37 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index e6416bbaf1bf6..60db34095a255 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -428,6 +428,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + { + struct net_device *bond_dev = xs->xso.dev; + struct net_device *real_dev; ++ netdevice_tracker tracker; + struct bond_ipsec *ipsec; + struct bonding *bond; + struct slave *slave; +@@ -439,24 +440,26 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + rcu_read_lock(); + bond = netdev_priv(bond_dev); + slave = rcu_dereference(bond->curr_active_slave); +- if (!slave) { +- rcu_read_unlock(); +- return -ENODEV; ++ real_dev = slave ? slave->dev : NULL; ++ netdev_hold(real_dev, &tracker, GFP_ATOMIC); ++ rcu_read_unlock(); ++ if (!real_dev) { ++ err = -ENODEV; ++ goto out; + } + +- real_dev = slave->dev; + if (!real_dev->xfrmdev_ops || + !real_dev->xfrmdev_ops->xdo_dev_state_add || + netif_is_bond_master(real_dev)) { + NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload"); +- rcu_read_unlock(); +- return -EINVAL; ++ err = -EINVAL; ++ goto out; + } + +- ipsec = kmalloc(sizeof(*ipsec), GFP_ATOMIC); ++ ipsec = kmalloc(sizeof(*ipsec), GFP_KERNEL); + if (!ipsec) { +- rcu_read_unlock(); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto out; + } + + xs->xso.real_dev = real_dev; +@@ -464,13 +467,14 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + if (!err) { + ipsec->xs = xs; + INIT_LIST_HEAD(&ipsec->list); +- spin_lock_bh(&bond->ipsec_lock); ++ mutex_lock(&bond->ipsec_lock); + list_add(&ipsec->list, &bond->ipsec_list); +- spin_unlock_bh(&bond->ipsec_lock); ++ mutex_unlock(&bond->ipsec_lock); + } else { + kfree(ipsec); + } +- rcu_read_unlock(); ++out: ++ netdev_put(real_dev, &tracker); + return err; + } + +@@ -481,35 +485,35 @@ static void bond_ipsec_add_sa_all(struct bonding *bond) + struct bond_ipsec *ipsec; + struct slave *slave; + +- rcu_read_lock(); +- slave = rcu_dereference(bond->curr_active_slave); +- if (!slave) +- goto out; ++ slave = rtnl_dereference(bond->curr_active_slave); ++ real_dev = slave ? slave->dev : NULL; ++ if (!real_dev) ++ return; + +- real_dev = slave->dev; ++ mutex_lock(&bond->ipsec_lock); + if (!real_dev->xfrmdev_ops || + !real_dev->xfrmdev_ops->xdo_dev_state_add || + netif_is_bond_master(real_dev)) { +- spin_lock_bh(&bond->ipsec_lock); + if (!list_empty(&bond->ipsec_list)) + slave_warn(bond_dev, real_dev, + "%s: no slave xdo_dev_state_add\n", + __func__); +- spin_unlock_bh(&bond->ipsec_lock); + goto out; + } + +- spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { ++ /* If new state is added before ipsec_lock acquired */ ++ if (ipsec->xs->xso.real_dev == real_dev) ++ continue; ++ + ipsec->xs->xso.real_dev = real_dev; + if (real_dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) { + slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__); + ipsec->xs->xso.real_dev = NULL; + } + } +- spin_unlock_bh(&bond->ipsec_lock); + out: +- rcu_read_unlock(); ++ mutex_unlock(&bond->ipsec_lock); + } + + /** +@@ -520,6 +524,7 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + { + struct net_device *bond_dev = xs->xso.dev; + struct net_device *real_dev; ++ netdevice_tracker tracker; + struct bond_ipsec *ipsec; + struct bonding *bond; + struct slave *slave; +@@ -530,6 +535,9 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + rcu_read_lock(); + bond = netdev_priv(bond_dev); + slave = rcu_dereference(bond->curr_active_slave); ++ real_dev = slave ? slave->dev : NULL; ++ netdev_hold(real_dev, &tracker, GFP_ATOMIC); ++ rcu_read_unlock(); + + if (!slave) + goto out; +@@ -537,7 +545,6 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + if (!xs->xso.real_dev) + goto out; + +- real_dev = slave->dev; + WARN_ON(xs->xso.real_dev != real_dev); + + if (!real_dev->xfrmdev_ops || +@@ -549,7 +556,8 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + + real_dev->xfrmdev_ops->xdo_dev_state_delete(xs); + out: +- spin_lock_bh(&bond->ipsec_lock); ++ netdev_put(real_dev, &tracker); ++ mutex_lock(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { + if (ipsec->xs == xs) { + list_del(&ipsec->list); +@@ -557,8 +565,7 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + break; + } + } +- spin_unlock_bh(&bond->ipsec_lock); +- rcu_read_unlock(); ++ mutex_unlock(&bond->ipsec_lock); + } + + static void bond_ipsec_del_sa_all(struct bonding *bond) +@@ -568,15 +575,12 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) + struct bond_ipsec *ipsec; + struct slave *slave; + +- rcu_read_lock(); +- slave = rcu_dereference(bond->curr_active_slave); +- if (!slave) { +- rcu_read_unlock(); ++ slave = rtnl_dereference(bond->curr_active_slave); ++ real_dev = slave ? slave->dev : NULL; ++ if (!real_dev) + return; +- } + +- real_dev = slave->dev; +- spin_lock_bh(&bond->ipsec_lock); ++ mutex_lock(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { + if (!ipsec->xs->xso.real_dev) + continue; +@@ -593,8 +597,7 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) + real_dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs); + } + } +- spin_unlock_bh(&bond->ipsec_lock); +- rcu_read_unlock(); ++ mutex_unlock(&bond->ipsec_lock); + } + + static void bond_ipsec_free_sa(struct xfrm_state *xs) +@@ -5921,7 +5924,7 @@ void bond_setup(struct net_device *bond_dev) + /* set up xfrm device ops (only supported in active-backup right now) */ + bond_dev->xfrmdev_ops = &bond_xfrmdev_ops; + INIT_LIST_HEAD(&bond->ipsec_list); +- spin_lock_init(&bond->ipsec_lock); ++ mutex_init(&bond->ipsec_lock); + #endif /* CONFIG_XFRM_OFFLOAD */ + + /* don't acquire bond device's netif_tx_lock when transmitting */ +@@ -5970,6 +5973,10 @@ static void bond_uninit(struct net_device *bond_dev) + __bond_release_one(bond_dev, slave->dev, true, true); + netdev_info(bond_dev, "Released all slaves\n"); + ++#ifdef CONFIG_XFRM_OFFLOAD ++ mutex_destroy(&bond->ipsec_lock); ++#endif /* CONFIG_XFRM_OFFLOAD */ ++ + bond_set_slave_arr(bond, NULL, NULL); + + list_del_rcu(&bond->bond_list); +diff --git a/include/net/bonding.h b/include/net/bonding.h +index b61fb1aa3a56b..8bb5f016969f1 100644 +--- a/include/net/bonding.h ++++ b/include/net/bonding.h +@@ -260,7 +260,7 @@ struct bonding { + #ifdef CONFIG_XFRM_OFFLOAD + struct list_head ipsec_list; + /* protecting ipsec_list */ +- spinlock_t ipsec_lock; ++ struct mutex ipsec_lock; + #endif /* CONFIG_XFRM_OFFLOAD */ + struct bpf_prog *xdp_prog; + }; +-- +2.43.0 + diff --git a/queue-6.10/bonding-extract-the-use-of-real_device-into-local-va.patch b/queue-6.10/bonding-extract-the-use-of-real_device-into-local-va.patch new file mode 100644 index 00000000000..fce28c30d15 --- /dev/null +++ b/queue-6.10/bonding-extract-the-use-of-real_device-into-local-va.patch @@ -0,0 +1,175 @@ +From 38730fd37e9bf07b8f07a6939c00be3f1d72875b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 06:10:55 +0300 +Subject: bonding: extract the use of real_device into local variable + +From: Jianbo Liu + +[ Upstream commit 907ed83a7583e8ffede88c5ac088392701a7d458 ] + +Add a local variable for slave->dev, to prepare for the lock change in +the next patch. There is no functionality change. + +Fixes: 9a5605505d9c ("bonding: Add struct bond_ipesc to manage SA") +Signed-off-by: Jianbo Liu +Reviewed-by: Cosmin Ratiu +Signed-off-by: Tariq Toukan +Reviewed-by: Hangbin Liu +Acked-by: Jay Vosburgh +Link: https://patch.msgid.link/20240823031056.110999-3-jianbol@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 58 +++++++++++++++++++-------------- + 1 file changed, 33 insertions(+), 25 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 232e592389638..e6416bbaf1bf6 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -427,6 +427,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + struct netlink_ext_ack *extack) + { + struct net_device *bond_dev = xs->xso.dev; ++ struct net_device *real_dev; + struct bond_ipsec *ipsec; + struct bonding *bond; + struct slave *slave; +@@ -443,9 +444,10 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + return -ENODEV; + } + +- if (!slave->dev->xfrmdev_ops || +- !slave->dev->xfrmdev_ops->xdo_dev_state_add || +- netif_is_bond_master(slave->dev)) { ++ real_dev = slave->dev; ++ if (!real_dev->xfrmdev_ops || ++ !real_dev->xfrmdev_ops->xdo_dev_state_add || ++ netif_is_bond_master(real_dev)) { + NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload"); + rcu_read_unlock(); + return -EINVAL; +@@ -456,9 +458,9 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + rcu_read_unlock(); + return -ENOMEM; + } +- xs->xso.real_dev = slave->dev; + +- err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs, extack); ++ xs->xso.real_dev = real_dev; ++ err = real_dev->xfrmdev_ops->xdo_dev_state_add(xs, extack); + if (!err) { + ipsec->xs = xs; + INIT_LIST_HEAD(&ipsec->list); +@@ -475,6 +477,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs, + static void bond_ipsec_add_sa_all(struct bonding *bond) + { + struct net_device *bond_dev = bond->dev; ++ struct net_device *real_dev; + struct bond_ipsec *ipsec; + struct slave *slave; + +@@ -483,12 +486,13 @@ static void bond_ipsec_add_sa_all(struct bonding *bond) + if (!slave) + goto out; + +- if (!slave->dev->xfrmdev_ops || +- !slave->dev->xfrmdev_ops->xdo_dev_state_add || +- netif_is_bond_master(slave->dev)) { ++ real_dev = slave->dev; ++ if (!real_dev->xfrmdev_ops || ++ !real_dev->xfrmdev_ops->xdo_dev_state_add || ++ netif_is_bond_master(real_dev)) { + spin_lock_bh(&bond->ipsec_lock); + if (!list_empty(&bond->ipsec_list)) +- slave_warn(bond_dev, slave->dev, ++ slave_warn(bond_dev, real_dev, + "%s: no slave xdo_dev_state_add\n", + __func__); + spin_unlock_bh(&bond->ipsec_lock); +@@ -497,9 +501,9 @@ static void bond_ipsec_add_sa_all(struct bonding *bond) + + spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { +- ipsec->xs->xso.real_dev = slave->dev; +- if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) { +- slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__); ++ ipsec->xs->xso.real_dev = real_dev; ++ if (real_dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) { ++ slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__); + ipsec->xs->xso.real_dev = NULL; + } + } +@@ -515,6 +519,7 @@ static void bond_ipsec_add_sa_all(struct bonding *bond) + static void bond_ipsec_del_sa(struct xfrm_state *xs) + { + struct net_device *bond_dev = xs->xso.dev; ++ struct net_device *real_dev; + struct bond_ipsec *ipsec; + struct bonding *bond; + struct slave *slave; +@@ -532,16 +537,17 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + if (!xs->xso.real_dev) + goto out; + +- WARN_ON(xs->xso.real_dev != slave->dev); ++ real_dev = slave->dev; ++ WARN_ON(xs->xso.real_dev != real_dev); + +- if (!slave->dev->xfrmdev_ops || +- !slave->dev->xfrmdev_ops->xdo_dev_state_delete || +- netif_is_bond_master(slave->dev)) { +- slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__); ++ if (!real_dev->xfrmdev_ops || ++ !real_dev->xfrmdev_ops->xdo_dev_state_delete || ++ netif_is_bond_master(real_dev)) { ++ slave_warn(bond_dev, real_dev, "%s: no slave xdo_dev_state_delete\n", __func__); + goto out; + } + +- slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs); ++ real_dev->xfrmdev_ops->xdo_dev_state_delete(xs); + out: + spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { +@@ -558,6 +564,7 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) + static void bond_ipsec_del_sa_all(struct bonding *bond) + { + struct net_device *bond_dev = bond->dev; ++ struct net_device *real_dev; + struct bond_ipsec *ipsec; + struct slave *slave; + +@@ -568,21 +575,22 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) + return; + } + ++ real_dev = slave->dev; + spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { + if (!ipsec->xs->xso.real_dev) + continue; + +- if (!slave->dev->xfrmdev_ops || +- !slave->dev->xfrmdev_ops->xdo_dev_state_delete || +- netif_is_bond_master(slave->dev)) { +- slave_warn(bond_dev, slave->dev, ++ if (!real_dev->xfrmdev_ops || ++ !real_dev->xfrmdev_ops->xdo_dev_state_delete || ++ netif_is_bond_master(real_dev)) { ++ slave_warn(bond_dev, real_dev, + "%s: no slave xdo_dev_state_delete\n", + __func__); + } else { +- slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs); +- if (slave->dev->xfrmdev_ops->xdo_dev_state_free) +- slave->dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs); ++ real_dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs); ++ if (real_dev->xfrmdev_ops->xdo_dev_state_free) ++ real_dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs); + } + } + spin_unlock_bh(&bond->ipsec_lock); +-- +2.43.0 + diff --git a/queue-6.10/bonding-implement-xdo_dev_state_free-and-call-it-aft.patch b/queue-6.10/bonding-implement-xdo_dev_state_free-and-call-it-aft.patch new file mode 100644 index 00000000000..134052a0c30 --- /dev/null +++ b/queue-6.10/bonding-implement-xdo_dev_state_free-and-call-it-aft.patch @@ -0,0 +1,94 @@ +From 42c832ee48ea969e1bcd785672073b5e3679186a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 06:10:54 +0300 +Subject: bonding: implement xdo_dev_state_free and call it after deletion + +From: Jianbo Liu + +[ Upstream commit ec13009472f4a756288eb4e18e20a7845da98d10 ] + +Add this implementation for bonding, so hardware resources can be +freed from the active slave after xfrm state is deleted. The netdev +used to invoke xdo_dev_state_free callback, is saved in the xfrm state +(xs->xso.real_dev), which is also the bond's active slave. To prevent +it from being freed, acquire netdev reference before leaving RCU +read-side critical section, and release it after callback is done. + +And call it when deleting all SAs from old active real interface while +switching current active slave. + +Fixes: 9a5605505d9c ("bonding: Add struct bond_ipesc to manage SA") +Signed-off-by: Jianbo Liu +Signed-off-by: Tariq Toukan +Reviewed-by: Hangbin Liu +Acked-by: Jay Vosburgh +Link: https://patch.msgid.link/20240823031056.110999-2-jianbol@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 36 +++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index b257504a85347..232e592389638 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -581,12 +581,47 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) + __func__); + } else { + slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs); ++ if (slave->dev->xfrmdev_ops->xdo_dev_state_free) ++ slave->dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs); + } + } + spin_unlock_bh(&bond->ipsec_lock); + rcu_read_unlock(); + } + ++static void bond_ipsec_free_sa(struct xfrm_state *xs) ++{ ++ struct net_device *bond_dev = xs->xso.dev; ++ struct net_device *real_dev; ++ netdevice_tracker tracker; ++ struct bonding *bond; ++ struct slave *slave; ++ ++ if (!bond_dev) ++ return; ++ ++ rcu_read_lock(); ++ bond = netdev_priv(bond_dev); ++ slave = rcu_dereference(bond->curr_active_slave); ++ real_dev = slave ? slave->dev : NULL; ++ netdev_hold(real_dev, &tracker, GFP_ATOMIC); ++ rcu_read_unlock(); ++ ++ if (!slave) ++ goto out; ++ ++ if (!xs->xso.real_dev) ++ goto out; ++ ++ WARN_ON(xs->xso.real_dev != real_dev); ++ ++ if (real_dev && real_dev->xfrmdev_ops && ++ real_dev->xfrmdev_ops->xdo_dev_state_free) ++ real_dev->xfrmdev_ops->xdo_dev_state_free(xs); ++out: ++ netdev_put(real_dev, &tracker); ++} ++ + /** + * bond_ipsec_offload_ok - can this packet use the xfrm hw offload + * @skb: current data packet +@@ -627,6 +662,7 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) + static const struct xfrmdev_ops bond_xfrmdev_ops = { + .xdo_dev_state_add = bond_ipsec_add_sa, + .xdo_dev_state_delete = bond_ipsec_del_sa, ++ .xdo_dev_state_free = bond_ipsec_free_sa, + .xdo_dev_offload_ok = bond_ipsec_offload_ok, + }; + #endif /* CONFIG_XFRM_OFFLOAD */ +-- +2.43.0 + diff --git a/queue-6.10/cpufreq-amd-pstate-ut-don-t-check-for-highest-perf-m.patch b/queue-6.10/cpufreq-amd-pstate-ut-don-t-check-for-highest-perf-m.patch new file mode 100644 index 00000000000..b755f79a6f8 --- /dev/null +++ b/queue-6.10/cpufreq-amd-pstate-ut-don-t-check-for-highest-perf-m.patch @@ -0,0 +1,53 @@ +From b6046937ee7b3e2b65221d2fc5c06127ff15778d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2024 12:15:14 -0500 +Subject: cpufreq/amd-pstate-ut: Don't check for highest perf matching on + prefcore + +From: Mario Limonciello + +[ Upstream commit 9983a9cd4d429dc9ca01770083c4c1f366214b65 ] + +If a system is using preferred cores the highest perf will be inconsistent +as it can change from system events. + +Skip the checks for it. + +Fixes: e571a5e2068e ("cpufreq: amd-pstate: Update amd-pstate preferred core ranking dynamically") +Reviewed-by: Gautham R. Shenoy +Signed-off-by: Mario Limonciello +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/amd-pstate-ut.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c +index 66b73c308ce67..b7318669485e4 100644 +--- a/drivers/cpufreq/amd-pstate-ut.c ++++ b/drivers/cpufreq/amd-pstate-ut.c +@@ -160,14 +160,17 @@ static void amd_pstate_ut_check_perf(u32 index) + lowest_perf = AMD_CPPC_LOWEST_PERF(cap1); + } + +- if ((highest_perf != READ_ONCE(cpudata->highest_perf)) || +- (nominal_perf != READ_ONCE(cpudata->nominal_perf)) || ++ if (highest_perf != READ_ONCE(cpudata->highest_perf) && !cpudata->hw_prefcore) { ++ pr_err("%s cpu%d highest=%d %d highest perf doesn't match\n", ++ __func__, cpu, highest_perf, cpudata->highest_perf); ++ goto skip_test; ++ } ++ if ((nominal_perf != READ_ONCE(cpudata->nominal_perf)) || + (lowest_nonlinear_perf != READ_ONCE(cpudata->lowest_nonlinear_perf)) || + (lowest_perf != READ_ONCE(cpudata->lowest_perf))) { + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; +- pr_err("%s cpu%d highest=%d %d nominal=%d %d lowest_nonlinear=%d %d lowest=%d %d, they should be equal!\n", +- __func__, cpu, highest_perf, cpudata->highest_perf, +- nominal_perf, cpudata->nominal_perf, ++ pr_err("%s cpu%d nominal=%d %d lowest_nonlinear=%d %d lowest=%d %d, they should be equal!\n", ++ __func__, cpu, nominal_perf, cpudata->nominal_perf, + lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf, + lowest_perf, cpudata->lowest_perf); + goto skip_test; +-- +2.43.0 + diff --git a/queue-6.10/dmaengine-dw-add-memory-bus-width-verification.patch b/queue-6.10/dmaengine-dw-add-memory-bus-width-verification.patch new file mode 100644 index 00000000000..b31441e9a69 --- /dev/null +++ b/queue-6.10/dmaengine-dw-add-memory-bus-width-verification.patch @@ -0,0 +1,186 @@ +From 7b026109e958d0115e4ea85feb2f5a2a1dbd212d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Aug 2024 10:50:47 +0300 +Subject: dmaengine: dw: Add memory bus width verification + +From: Serge Semin + +[ Upstream commit d04b21bfa1c50a2ade4816cab6fdc91827b346b1 ] + +Currently in case of the DEV_TO_MEM or MEM_TO_DEV DMA transfers the memory +data width (single transfer width) is determined based on the buffer +length, buffer base address or DMA master-channel max address width +capability. It isn't enough in case of the channel disabling prior the +block transfer is finished. Here is what DW AHB DMA IP-core databook says +regarding the port suspension (DMA-transfer pause) implementation in the +controller: + +"When CTLx.SRC_TR_WIDTH < CTLx.DST_TR_WIDTH and the CFGx.CH_SUSP bit is +high, the CFGx.FIFO_EMPTY is asserted once the contents of the FIFO do not +permit a single word of CTLx.DST_TR_WIDTH to be formed. However, there may +still be data in the channel FIFO, but not enough to form a single +transfer of CTLx.DST_TR_WIDTH. In this scenario, once the channel is +disabled, the remaining data in the channel FIFO is not transferred to the +destination peripheral." + +So in case if the port gets to be suspended and then disabled it's +possible to have the data silently discarded even though the controller +reported that FIFO is empty and the CTLx.BLOCK_TS indicated the dropped +data already received from the source device. This looks as if the data +somehow got lost on a way from the peripheral device to memory and causes +problems for instance in the DW APB UART driver, which pauses and disables +the DMA-transfer as soon as the recv data timeout happens. Here is the way +it looks: + + Memory <------- DMA FIFO <------ UART FIFO <---------------- UART + DST_TR_WIDTH -+--------| | | + | | | | No more data + Current lvl -+--------| |---------+- DMA-burst lvl + | | |---------+- Leftover data + | | |---------+- SRC_TR_WIDTH + -+--------+-------+---------+ + +In the example above: no more data is getting received over the UART port +and BLOCK_TS is not even close to be fully received; some data is left in +the UART FIFO, but not enough to perform a bursted DMA-xfer to the DMA +FIFO; some data is left in the DMA FIFO, but not enough to be passed +further to the system memory in a single transfer. In this situation the +8250 UART driver catches the recv timeout interrupt, pauses the +DMA-transfer and terminates it completely, after which the IRQ handler +manually fetches the leftover data from the UART FIFO into the +recv-buffer. But since the DMA-channel has been disabled with the data +left in the DMA FIFO, that data will be just discarded and the recv-buffer +will have a gap of the "current lvl" size in the recv-buffer at the tail +of the lately received data portion. So the data will be lost just due to +the misconfigured DMA transfer. + +Note this is only relevant for the case of the transfer suspension and +_disabling_. No problem will happen if the transfer will be re-enabled +afterwards or the block transfer is fully completed. In the later case the +"FIFO flush mode" will be executed at the transfer final stage in order to +push out the data left in the DMA FIFO. + +In order to fix the denoted problem the DW AHB DMA-engine driver needs to +make sure that the _bursted_ source transfer width is greater or equal to +the single destination transfer (note the HW databook describes more +strict constraint than actually required). Since the peripheral-device +side is prescribed by the client driver logic, the memory-side can be only +used for that. The solution can be easily implemented for the DEV_TO_MEM +transfers just by adjusting the memory-channel address width. Sadly it's +not that easy for the MEM_TO_DEV transfers since the mem-to-dma burst size +is normally dynamically determined by the controller. So the only thing +that can be done is to make sure that memory-side address width is greater +than the peripheral device address width. + +Fixes: a09820043c9e ("dw_dmac: autoconfigure data_width or get it via platform data") +Signed-off-by: Serge Semin +Acked-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20240802075100.6475-3-fancer.lancer@gmail.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/dw/core.c | 51 +++++++++++++++++++++++++++++++++++++------ + 1 file changed, 44 insertions(+), 7 deletions(-) + +diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c +index 11e269a31a092..b341a6f1b0438 100644 +--- a/drivers/dma/dw/core.c ++++ b/drivers/dma/dw/core.c +@@ -622,12 +622,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + struct dw_desc *prev; + struct dw_desc *first; + u32 ctllo, ctlhi; +- u8 m_master = dwc->dws.m_master; +- u8 lms = DWC_LLP_LMS(m_master); ++ u8 lms = DWC_LLP_LMS(dwc->dws.m_master); + dma_addr_t reg; + unsigned int reg_width; + unsigned int mem_width; +- unsigned int data_width = dw->pdata->data_width[m_master]; + unsigned int i; + struct scatterlist *sg; + size_t total_len = 0; +@@ -661,7 +659,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + mem = sg_dma_address(sg); + len = sg_dma_len(sg); + +- mem_width = __ffs(data_width | mem | len); ++ mem_width = __ffs(sconfig->src_addr_width | mem | len); + + slave_sg_todev_fill_desc: + desc = dwc_desc_get(dwc); +@@ -721,7 +719,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + lli_write(desc, sar, reg); + lli_write(desc, dar, mem); + lli_write(desc, ctlhi, ctlhi); +- mem_width = __ffs(data_width | mem); ++ mem_width = __ffs(sconfig->dst_addr_width | mem); + lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width)); + desc->len = dlen; + +@@ -813,6 +811,41 @@ static int dwc_verify_p_buswidth(struct dma_chan *chan) + return 0; + } + ++static int dwc_verify_m_buswidth(struct dma_chan *chan) ++{ ++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan); ++ struct dw_dma *dw = to_dw_dma(chan->device); ++ u32 reg_width, reg_burst, mem_width; ++ ++ mem_width = dw->pdata->data_width[dwc->dws.m_master]; ++ ++ /* ++ * It's possible to have a data portion locked in the DMA FIFO in case ++ * of the channel suspension. Subsequent channel disabling will cause ++ * that data silent loss. In order to prevent that maintain the src and ++ * dst transfer widths coherency by means of the relation: ++ * (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH) ++ * Look for the details in the commit message that brings this change. ++ * ++ * Note the DMA configs utilized in the calculations below must have ++ * been verified to have correct values by this method call. ++ */ ++ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) { ++ reg_width = dwc->dma_sconfig.dst_addr_width; ++ if (mem_width < reg_width) ++ return -EINVAL; ++ ++ dwc->dma_sconfig.src_addr_width = mem_width; ++ } else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) { ++ reg_width = dwc->dma_sconfig.src_addr_width; ++ reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst); ++ ++ dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst); ++ } ++ ++ return 0; ++} ++ + static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) + { + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); +@@ -822,14 +855,18 @@ static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) + memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); + + dwc->dma_sconfig.src_maxburst = +- clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst); ++ clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst); + dwc->dma_sconfig.dst_maxburst = +- clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst); ++ clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst); + + ret = dwc_verify_p_buswidth(chan); + if (ret) + return ret; + ++ ret = dwc_verify_m_buswidth(chan); ++ if (ret) ++ return ret; ++ + dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst); + dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst); + +-- +2.43.0 + diff --git a/queue-6.10/dmaengine-dw-add-peripheral-bus-width-verification.patch b/queue-6.10/dmaengine-dw-add-peripheral-bus-width-verification.patch new file mode 100644 index 00000000000..e771161c0d4 --- /dev/null +++ b/queue-6.10/dmaengine-dw-add-peripheral-bus-width-verification.patch @@ -0,0 +1,112 @@ +From cb0f43133706cc057161f93551cbb35626e9c9c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Aug 2024 10:50:46 +0300 +Subject: dmaengine: dw: Add peripheral bus width verification + +From: Serge Semin + +[ Upstream commit b336268dde75cb09bd795cb24893d52152a9191f ] + +Currently the src_addr_width and dst_addr_width fields of the +dma_slave_config structure are mapped to the CTLx.SRC_TR_WIDTH and +CTLx.DST_TR_WIDTH fields of the peripheral bus side in order to have the +properly aligned data passed to the target device. It's done just by +converting the passed peripheral bus width to the encoded value using the +__ffs() function. This implementation has several problematic sides: + +1. __ffs() is undefined if no bit exist in the passed value. Thus if the +specified addr-width is DMA_SLAVE_BUSWIDTH_UNDEFINED, __ffs() may return +unexpected value depending on the platform-specific implementation. + +2. DW AHB DMA-engine permits having the power-of-2 transfer width limited +by the DMAH_Mk_HDATA_WIDTH IP-core synthesize parameter. Specifying +bus-width out of that constraints scope will definitely cause unexpected +result since the destination reg will be only partly touched than the +client driver implied. + +Let's fix all of that by adding the peripheral bus width verification +method and calling it in dwc_config() which is supposed to be executed +before preparing any transfer. The new method will make sure that the +passed source or destination address width is valid and if undefined then +the driver will just fallback to the 1-byte width transfer. + +Fixes: 029a40e97d0d ("dmaengine: dw: provide DMA capabilities") +Signed-off-by: Serge Semin +Acked-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20240802075100.6475-2-fancer.lancer@gmail.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/dw/core.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c +index 5f7d690e3dbae..11e269a31a092 100644 +--- a/drivers/dma/dw/core.c ++++ b/drivers/dma/dw/core.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -780,10 +781,43 @@ bool dw_dma_filter(struct dma_chan *chan, void *param) + } + EXPORT_SYMBOL_GPL(dw_dma_filter); + ++static int dwc_verify_p_buswidth(struct dma_chan *chan) ++{ ++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan); ++ struct dw_dma *dw = to_dw_dma(chan->device); ++ u32 reg_width, max_width; ++ ++ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) ++ reg_width = dwc->dma_sconfig.dst_addr_width; ++ else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) ++ reg_width = dwc->dma_sconfig.src_addr_width; ++ else /* DMA_MEM_TO_MEM */ ++ return 0; ++ ++ max_width = dw->pdata->data_width[dwc->dws.p_master]; ++ ++ /* Fall-back to 1-byte transfer width if undefined */ ++ if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) ++ reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE; ++ else if (!is_power_of_2(reg_width) || reg_width > max_width) ++ return -EINVAL; ++ else /* bus width is valid */ ++ return 0; ++ ++ /* Update undefined addr width value */ ++ if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) ++ dwc->dma_sconfig.dst_addr_width = reg_width; ++ else /* DMA_DEV_TO_MEM */ ++ dwc->dma_sconfig.src_addr_width = reg_width; ++ ++ return 0; ++} ++ + static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) + { + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); + struct dw_dma *dw = to_dw_dma(chan->device); ++ int ret; + + memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); + +@@ -792,6 +826,10 @@ static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig) + dwc->dma_sconfig.dst_maxburst = + clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst); + ++ ret = dwc_verify_p_buswidth(chan); ++ if (ret) ++ return ret; ++ + dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst); + dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst); + +-- +2.43.0 + diff --git a/queue-6.10/dmaengine-ti-omap-dma-initialize-sglen-after-allocat.patch b/queue-6.10/dmaengine-ti-omap-dma-initialize-sglen-after-allocat.patch new file mode 100644 index 00000000000..e86d18a97b4 --- /dev/null +++ b/queue-6.10/dmaengine-ti-omap-dma-initialize-sglen-after-allocat.patch @@ -0,0 +1,71 @@ +From 994f491a754c776e1214e786b35bc5feafb72eeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jul 2024 14:57:06 -0700 +Subject: dmaengine: ti: omap-dma: Initialize sglen after allocation + +From: Kees Cook + +[ Upstream commit 5e5c793c7fc47219998465361d94510fdf55d83f ] + +With the new __counted_by annocation, the "sglen" struct member must +be set before accessing the "sg" array. This initialization was done in +other places where a new struct omap_desc is allocated, but these cases +were missed. Set "sglen" after allocation. + +Fixes: b85178611c11 ("dmaengine: ti: omap-dma: Annotate struct omap_desc with __counted_by") +Signed-off-by: Kees Cook +Reviewed-by: Gustavo A. R. Silva +Link: https://lore.kernel.org/r/20240716215702.work.802-kees@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/ti/omap-dma.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c +index b9e0e22383b72..984fbec2c4bae 100644 +--- a/drivers/dma/ti/omap-dma.c ++++ b/drivers/dma/ti/omap-dma.c +@@ -1186,10 +1186,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( + d->dev_addr = dev_addr; + d->fi = burst; + d->es = es; ++ d->sglen = 1; + d->sg[0].addr = buf_addr; + d->sg[0].en = period_len / es_bytes[es]; + d->sg[0].fn = buf_len / period_len; +- d->sglen = 1; + + d->ccr = c->ccr; + if (dir == DMA_DEV_TO_MEM) +@@ -1258,10 +1258,10 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy( + d->dev_addr = src; + d->fi = 0; + d->es = data_type; ++ d->sglen = 1; + d->sg[0].en = len / BIT(data_type); + d->sg[0].fn = 1; + d->sg[0].addr = dest; +- d->sglen = 1; + d->ccr = c->ccr; + d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC; + +@@ -1309,6 +1309,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( + if (data_type > CSDP_DATA_TYPE_32) + data_type = CSDP_DATA_TYPE_32; + ++ d->sglen = 1; + sg = &d->sg[0]; + d->dir = DMA_MEM_TO_MEM; + d->dev_addr = xt->src_start; +@@ -1316,7 +1317,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( + sg->en = xt->sgl[0].size / BIT(data_type); + sg->fn = xt->numf; + sg->addr = xt->dst_start; +- d->sglen = 1; + d->ccr = c->ccr; + + src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]); +-- +2.43.0 + diff --git a/queue-6.10/drm-amd-display-avoid-using-null-object-of-framebuff.patch b/queue-6.10/drm-amd-display-avoid-using-null-object-of-framebuff.patch new file mode 100644 index 00000000000..41c24cb8646 --- /dev/null +++ b/queue-6.10/drm-amd-display-avoid-using-null-object-of-framebuff.patch @@ -0,0 +1,54 @@ +From d8766f45dcb6fa3dac0c3d0d89194d4ee3959ec8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 12:27:24 +0800 +Subject: drm/amd/display: avoid using null object of framebuffer + +From: Ma Ke + +[ Upstream commit 3b9a33235c773c7a3768060cf1d2cf8a9153bc37 ] + +Instead of using state->fb->obj[0] directly, get object from framebuffer +by calling drm_gem_fb_get_obj() and return error code when object is +null to avoid using null object of framebuffer. + +Fixes: 5d945cbcd4b1 ("drm/amd/display: Create a file dedicated to planes") +Signed-off-by: Ma Ke +Signed-off-by: Alex Deucher +(cherry picked from commit 73dd0ad9e5dad53766ea3e631303430116f834b3) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index 311c62d2d1ebb..70e45d980bb93 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + + #include "amdgpu.h" +@@ -854,10 +855,14 @@ static int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane, + } + + afb = to_amdgpu_framebuffer(new_state->fb); +- obj = new_state->fb->obj[0]; ++ obj = drm_gem_fb_get_obj(new_state->fb, 0); ++ if (!obj) { ++ DRM_ERROR("Failed to get obj from framebuffer\n"); ++ return -EINVAL; ++ } ++ + rbo = gem_to_amdgpu_bo(obj); + adev = amdgpu_ttm_adev(rbo->tbo.bdev); +- + r = amdgpu_bo_reserve(rbo, true); + if (r) { + dev_err(adev->dev, "fail to reserve bo (%d)\n", r); +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-hwmon-fix-write_i1-param-from-u32-to-u16.patch b/queue-6.10/drm-xe-hwmon-fix-write_i1-param-from-u32-to-u16.patch new file mode 100644 index 00000000000..277c89680be --- /dev/null +++ b/queue-6.10/drm-xe-hwmon-fix-write_i1-param-from-u32-to-u16.patch @@ -0,0 +1,45 @@ +From 5397ab9e3e6fa73eaa7a574c6d6edad42c8c6309 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Aug 2024 21:23:01 +0530 +Subject: drm/xe/hwmon: Fix WRITE_I1 param from u32 to u16 + +From: Karthik Poosa + +[ Upstream commit 59d237c8a241168c7ae34c48244059b7bafaff38 ] + +WRITE_I1 sub-command of the POWER_SETUP pcode command accepts a u16 +parameter instead of u32. This change prevents potential illegal +sub-command errors. + +v2: Mask uval instead of changing the prototype. (Badal) + +v3: Rephrase commit message. (Badal) + +Signed-off-by: Karthik Poosa +Fixes: 92d44a422d0d ("drm/xe/hwmon: Expose card reactive critical power") +Reviewed-by: Badal Nilawar +Link: https://patchwork.freedesktop.org/patch/msgid/20240827155301.183383-1-karthik.poosa@intel.com +Signed-off-by: Rodrigo Vivi +(cherry picked from commit a7f657097e96d8fa745c74bb1a239ebd5a8c971c) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_hwmon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c +index d37f1dea9f8b8..bb815dbde63a6 100644 +--- a/drivers/gpu/drm/xe/xe_hwmon.c ++++ b/drivers/gpu/drm/xe/xe_hwmon.c +@@ -443,7 +443,7 @@ static int xe_hwmon_pcode_write_i1(struct xe_gt *gt, u32 uval) + { + return xe_pcode_write(gt, PCODE_MBOX(PCODE_POWER_SETUP, + POWER_SETUP_SUBCOMMAND_WRITE_I1, 0), +- uval); ++ (uval & POWER_SETUP_I1_DATA_MASK)); + } + + static int xe_hwmon_power_curr_crit_read(struct xe_hwmon *hwmon, int channel, +-- +2.43.0 + diff --git a/queue-6.10/ethtool-check-device-is-present-when-getting-link-se.patch b/queue-6.10/ethtool-check-device-is-present-when-getting-link-se.patch new file mode 100644 index 00000000000..e9f88f7c4c4 --- /dev/null +++ b/queue-6.10/ethtool-check-device-is-present-when-getting-link-se.patch @@ -0,0 +1,79 @@ +From de2359bdccd2836659f1597e96c572e4d4af7955 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 16:26:58 +1000 +Subject: ethtool: check device is present when getting link settings + +From: Jamie Bainbridge + +[ Upstream commit a699781c79ecf6cfe67fb00a0331b4088c7c8466 ] + +A sysfs reader can race with a device reset or removal, attempting to +read device state when the device is not actually present. eg: + + [exception RIP: qed_get_current_link+17] + #8 [ffffb9e4f2907c48] qede_get_link_ksettings at ffffffffc07a994a [qede] + #9 [ffffb9e4f2907cd8] __rh_call_get_link_ksettings at ffffffff992b01a3 + #10 [ffffb9e4f2907d38] __ethtool_get_link_ksettings at ffffffff992b04e4 + #11 [ffffb9e4f2907d90] duplex_show at ffffffff99260300 + #12 [ffffb9e4f2907e38] dev_attr_show at ffffffff9905a01c + #13 [ffffb9e4f2907e50] sysfs_kf_seq_show at ffffffff98e0145b + #14 [ffffb9e4f2907e68] seq_read at ffffffff98d902e3 + #15 [ffffb9e4f2907ec8] vfs_read at ffffffff98d657d1 + #16 [ffffb9e4f2907f00] ksys_read at ffffffff98d65c3f + #17 [ffffb9e4f2907f38] do_syscall_64 at ffffffff98a052fb + + crash> struct net_device.state ffff9a9d21336000 + state = 5, + +state 5 is __LINK_STATE_START (0b1) and __LINK_STATE_NOCARRIER (0b100). +The device is not present, note lack of __LINK_STATE_PRESENT (0b10). + +This is the same sort of panic as observed in commit 4224cfd7fb65 +("net-sysfs: add check for netdevice being present to speed_show"). + +There are many other callers of __ethtool_get_link_ksettings() which +don't have a device presence check. + +Move this check into ethtool to protect all callers. + +Fixes: d519e17e2d01 ("net: export device speed and duplex via sysfs") +Fixes: 4224cfd7fb65 ("net-sysfs: add check for netdevice being present to speed_show") +Signed-off-by: Jamie Bainbridge +Link: https://patch.msgid.link/8bae218864beaa44ed01628140475b9bf641c5b0.1724393671.git.jamie.bainbridge@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/net-sysfs.c | 2 +- + net/ethtool/ioctl.c | 3 +++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c +index 4c27a360c2948..dc91921da4ea0 100644 +--- a/net/core/net-sysfs.c ++++ b/net/core/net-sysfs.c +@@ -235,7 +235,7 @@ static ssize_t speed_show(struct device *dev, + if (!rtnl_trylock()) + return restart_syscall(); + +- if (netif_running(netdev) && netif_device_present(netdev)) { ++ if (netif_running(netdev)) { + struct ethtool_link_ksettings cmd; + + if (!__ethtool_get_link_ksettings(netdev, &cmd)) +diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c +index fcc3dbef8b503..f99fd564d0ee5 100644 +--- a/net/ethtool/ioctl.c ++++ b/net/ethtool/ioctl.c +@@ -441,6 +441,9 @@ int __ethtool_get_link_ksettings(struct net_device *dev, + if (!dev->ethtool_ops->get_link_ksettings) + return -EOPNOTSUPP; + ++ if (!netif_device_present(dev)) ++ return -ENODEV; ++ + memset(link_ksettings, 0, sizeof(*link_ksettings)); + return dev->ethtool_ops->get_link_ksettings(dev, link_ksettings); + } +-- +2.43.0 + diff --git a/queue-6.10/gtp-fix-a-potential-null-pointer-dereference.patch b/queue-6.10/gtp-fix-a-potential-null-pointer-dereference.patch new file mode 100644 index 00000000000..752e864b631 --- /dev/null +++ b/queue-6.10/gtp-fix-a-potential-null-pointer-dereference.patch @@ -0,0 +1,47 @@ +From 4c7270e846209580d2833078d4f6d8c6c64dc56c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Aug 2024 12:16:38 -0700 +Subject: gtp: fix a potential NULL pointer dereference + +From: Cong Wang + +[ Upstream commit defd8b3c37b0f9cb3e0f60f47d3d78d459d57fda ] + +When sockfd_lookup() fails, gtp_encap_enable_socket() returns a +NULL pointer, but its callers only check for error pointers thus miss +the NULL pointer case. + +Fix it by returning an error pointer with the error code carried from +sockfd_lookup(). + +(I found this bug during code inspection.) + +Fixes: 1e3a3abd8b28 ("gtp: make GTP sockets in gtp_newlink optional") +Cc: Andreas Schultz +Cc: Harald Welte +Signed-off-by: Cong Wang +Reviewed-by: Simon Horman +Reviewed-by: Pablo Neira Ayuso +Link: https://patch.msgid.link/20240825191638.146748-1-xiyou.wangcong@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/gtp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 0696faf60013e..2e94d10348cce 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1653,7 +1653,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int type, + sock = sockfd_lookup(fd, &err); + if (!sock) { + pr_debug("gtp socket fd=%d not found\n", fd); +- return NULL; ++ return ERR_PTR(err); + } + + sk = sock->sk; +-- +2.43.0 + diff --git a/queue-6.10/hwmon-pt5161l-fix-invalid-temperature-reading.patch b/queue-6.10/hwmon-pt5161l-fix-invalid-temperature-reading.patch new file mode 100644 index 00000000000..42cc93d6c79 --- /dev/null +++ b/queue-6.10/hwmon-pt5161l-fix-invalid-temperature-reading.patch @@ -0,0 +1,51 @@ +From 6795d41f4fc6530c62ea2c7aa22136099cb8d9ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 18:46:30 +0800 +Subject: hwmon: (pt5161l) Fix invalid temperature reading + +From: Cosmo Chou + +[ Upstream commit 7bbc079531fc38d401e1c4088d4981435a8828e3 ] + +The temperature reading function was using a signed long for the ADC +code, which could lead to mishandling of invalid codes on 32-bit +platforms. This allowed out-of-range ADC codes to be incorrectly +interpreted as valid values and used in temperature calculations. + +Change adc_code to u32 to ensure that invalid ADC codes are correctly +identified on all platforms. + +Fixes: 1b2ca93cd059 ("hwmon: Add driver for Astera Labs PT5161L retimer") +Signed-off-by: Cosmo Chou +Message-ID: <20240819104630.2375441-1-chou.cosmo@gmail.com> +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/pt5161l.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/hwmon/pt5161l.c b/drivers/hwmon/pt5161l.c +index b0d58a26d499d..a9f0b23f9e76e 100644 +--- a/drivers/hwmon/pt5161l.c ++++ b/drivers/hwmon/pt5161l.c +@@ -427,7 +427,7 @@ static int pt5161l_read(struct device *dev, enum hwmon_sensor_types type, + struct pt5161l_data *data = dev_get_drvdata(dev); + int ret; + u8 buf[8]; +- long adc_code; ++ u32 adc_code; + + switch (attr) { + case hwmon_temp_input: +@@ -449,7 +449,7 @@ static int pt5161l_read(struct device *dev, enum hwmon_sensor_types type, + + adc_code = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; + if (adc_code == 0 || adc_code >= 0x3ff) { +- dev_dbg(dev, "Invalid adc_code %lx\n", adc_code); ++ dev_dbg(dev, "Invalid adc_code %x\n", adc_code); + return -EIO; + } + +-- +2.43.0 + diff --git a/queue-6.10/io_uring-kbuf-return-correct-iovec-count-from-classi.patch b/queue-6.10/io_uring-kbuf-return-correct-iovec-count-from-classi.patch new file mode 100644 index 00000000000..885c405ca01 --- /dev/null +++ b/queue-6.10/io_uring-kbuf-return-correct-iovec-count-from-classi.patch @@ -0,0 +1,40 @@ +From 0b8c4de6d50e6eb0935b48b19d80c76fae2fd51a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Aug 2024 10:45:54 -0600 +Subject: io_uring/kbuf: return correct iovec count from classic buffer peek + +From: Jens Axboe + +[ Upstream commit f274495aea7b15225b3d83837121b22ef96e560c ] + +io_provided_buffers_select() returns 0 to indicate success, but it should +be returning 1 to indicate that 1 vec was mapped. This causes peeking +to fail with classic provided buffers, and while that's not a use case +that anyone should use, it should still work correctly. + +The end result is that no buffer will be selected, and hence a completion +with '0' as the result will be posted, without a buffer attached. + +Fixes: 35c8711c8fc4 ("io_uring/kbuf: add helpers for getting/peeking multiple buffers") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/kbuf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c +index 1af2bd56af44a..bdfa30b38321b 100644 +--- a/io_uring/kbuf.c ++++ b/io_uring/kbuf.c +@@ -129,7 +129,7 @@ static int io_provided_buffers_select(struct io_kiocb *req, size_t *len, + + iov[0].iov_base = buf; + iov[0].iov_len = *len; +- return 0; ++ return 1; + } + + static struct io_uring_buf *io_ring_head_to_buf(struct io_uring_buf_ring *br, +-- +2.43.0 + diff --git a/queue-6.10/iommu-do-not-return-0-from-map_pages-if-it-doesn-t-d.patch b/queue-6.10/iommu-do-not-return-0-from-map_pages-if-it-doesn-t-d.patch new file mode 100644 index 00000000000..5cfd8b89360 --- /dev/null +++ b/queue-6.10/iommu-do-not-return-0-from-map_pages-if-it-doesn-t-d.patch @@ -0,0 +1,84 @@ +From 859649c3231bd2bbfd2b938564a45776b5eb319a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 11:45:55 -0300 +Subject: iommu: Do not return 0 from map_pages if it doesn't do anything + +From: Jason Gunthorpe + +[ Upstream commit 6093cd582f8e027117a8d4ad5d129a1aacdc53d2 ] + +These three implementations of map_pages() all succeed if a mapping is +requested with no read or write. Since they return back to __iommu_map() +leaving the mapped output as 0 it triggers an infinite loop. Therefore +nothing is using no-access protection bits. + +Further, VFIO and iommufd rely on iommu_iova_to_phys() to get back PFNs +stored by map, if iommu_map() succeeds but iommu_iova_to_phys() fails that +will create serious bugs. + +Thus remove this never used "nothing to do" concept and just fail map +immediately. + +Fixes: e5fc9753b1a8 ("iommu/io-pgtable: Add ARMv7 short descriptor support") +Fixes: e1d3c0fd701d ("iommu: add ARM LPAE page table allocator") +Fixes: 745ef1092bcf ("iommu/io-pgtable: Move Apple DART support to its own file") +Signed-off-by: Jason Gunthorpe +Acked-by: Will Deacon +Reviewed-by: Kevin Tian +Link: https://lore.kernel.org/r/2-v1-1211e1294c27+4b1-iommu_no_prot_jgg@nvidia.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/io-pgtable-arm-v7s.c | 3 +-- + drivers/iommu/io-pgtable-arm.c | 3 +-- + drivers/iommu/io-pgtable-dart.c | 3 +-- + 3 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c +index 75f244a3e12df..06ffc683b28fe 100644 +--- a/drivers/iommu/io-pgtable-arm-v7s.c ++++ b/drivers/iommu/io-pgtable-arm-v7s.c +@@ -552,9 +552,8 @@ static int arm_v7s_map_pages(struct io_pgtable_ops *ops, unsigned long iova, + paddr >= (1ULL << data->iop.cfg.oas))) + return -ERANGE; + +- /* If no access, then nothing to do */ + if (!(prot & (IOMMU_READ | IOMMU_WRITE))) +- return 0; ++ return -EINVAL; + + while (pgcount--) { + ret = __arm_v7s_map(data, iova, paddr, pgsize, prot, 1, data->pgd, +diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c +index 3d23b924cec16..07c9b90eab2ed 100644 +--- a/drivers/iommu/io-pgtable-arm.c ++++ b/drivers/iommu/io-pgtable-arm.c +@@ -495,9 +495,8 @@ static int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova, + if (WARN_ON(iaext || paddr >> cfg->oas)) + return -ERANGE; + +- /* If no access, then nothing to do */ + if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) +- return 0; ++ return -EINVAL; + + prot = arm_lpae_prot_to_pte(data, iommu_prot); + ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl, +diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c +index ad28031e1e93d..c004640640ee5 100644 +--- a/drivers/iommu/io-pgtable-dart.c ++++ b/drivers/iommu/io-pgtable-dart.c +@@ -245,9 +245,8 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova, + if (WARN_ON(paddr >> cfg->oas)) + return -ERANGE; + +- /* If no access, then nothing to do */ + if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) +- return 0; ++ return -EINVAL; + + tbl = dart_get_table(data, iova); + +-- +2.43.0 + diff --git a/queue-6.10/net-busy-poll-use-ktime_get_ns-instead-of-local_cloc.patch b/queue-6.10/net-busy-poll-use-ktime_get_ns-instead-of-local_cloc.patch new file mode 100644 index 00000000000..8274cbed2e6 --- /dev/null +++ b/queue-6.10/net-busy-poll-use-ktime_get_ns-instead-of-local_cloc.patch @@ -0,0 +1,48 @@ +From 5c369548fe4bc50ffff3ad1a22eeb9806105134e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Aug 2024 11:49:16 +0000 +Subject: net: busy-poll: use ktime_get_ns() instead of local_clock() + +From: Eric Dumazet + +[ Upstream commit 0870b0d8b393dde53106678a1e2cec9dfa52f9b7 ] + +Typically, busy-polling durations are below 100 usec. + +When/if the busy-poller thread migrates to another cpu, +local_clock() can be off by +/-2msec or more for small +values of HZ, depending on the platform. + +Use ktimer_get_ns() to ensure deterministic behavior, +which is the whole point of busy-polling. + +Fixes: 060212928670 ("net: add low latency socket poll") +Fixes: 9a3c71aa8024 ("net: convert low latency sockets to sched_clock()") +Fixes: 37089834528b ("sched, net: Fixup busy_loop_us_clock()") +Signed-off-by: Eric Dumazet +Cc: Mina Almasry +Cc: Willem de Bruijn +Reviewed-by: Joe Damato +Link: https://patch.msgid.link/20240827114916.223377-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/busy_poll.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h +index 9b09acac538ee..522f1da8b747a 100644 +--- a/include/net/busy_poll.h ++++ b/include/net/busy_poll.h +@@ -68,7 +68,7 @@ static inline bool sk_can_busy_loop(struct sock *sk) + static inline unsigned long busy_loop_current_time(void) + { + #ifdef CONFIG_NET_RX_BUSY_POLL +- return (unsigned long)(local_clock() >> 10); ++ return (unsigned long)(ktime_get_ns() >> 10); + #else + return 0; + #endif +-- +2.43.0 + diff --git a/queue-6.10/net_sched-sch_fq-fix-incorrect-behavior-for-small-we.patch b/queue-6.10/net_sched-sch_fq-fix-incorrect-behavior-for-small-we.patch new file mode 100644 index 00000000000..1d94e27314d --- /dev/null +++ b/queue-6.10/net_sched-sch_fq-fix-incorrect-behavior-for-small-we.patch @@ -0,0 +1,50 @@ +From c08fbc679d4448404b971d7547f660cac0cdca7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 24 Aug 2024 18:19:01 +0000 +Subject: net_sched: sch_fq: fix incorrect behavior for small weights + +From: Eric Dumazet + +[ Upstream commit bc21000e99f92a6b5540d7267c6b22806c5c33d3 ] + +fq_dequeue() has a complex logic to find packets in one of the 3 bands. + +As Neal found out, it is possible that one band has a deficit smaller +than its weight. fq_dequeue() can return NULL while some packets are +elligible for immediate transmit. + +In this case, more than one iteration is needed to refill pband->credit. + +With default parameters (weights 589824 196608 65536) bug can trigger +if large BIG TCP packets are sent to the lowest priority band. + +Bisected-by: John Sperbeck +Diagnosed-by: Neal Cardwell +Fixes: 29f834aa326e ("net_sched: sch_fq: add 3 bands and WRR scheduling") +Signed-off-by: Eric Dumazet +Reviewed-by: Neal Cardwell +Link: https://patch.msgid.link/20240824181901.953776-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_fq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c +index 2389747256793..19a49af5a9e52 100644 +--- a/net/sched/sch_fq.c ++++ b/net/sched/sch_fq.c +@@ -663,7 +663,9 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch) + pband = &q->band_flows[q->band_nr]; + pband->credit = min(pband->credit + pband->quantum, + pband->quantum); +- goto begin; ++ if (pband->credit > 0) ++ goto begin; ++ retry = 0; + } + if (q->time_next_delayed_flow != ~0ULL) + qdisc_watchdog_schedule_range_ns(&q->watchdog, +-- +2.43.0 + diff --git a/queue-6.10/netfilter-nf_tables-restore-ip-sanity-checks-for-net.patch b/queue-6.10/netfilter-nf_tables-restore-ip-sanity-checks-for-net.patch new file mode 100644 index 00000000000..3daff527831 --- /dev/null +++ b/queue-6.10/netfilter-nf_tables-restore-ip-sanity-checks-for-net.patch @@ -0,0 +1,67 @@ +From 64fa84726b34fb6844b2c2047ffc421d432503fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 12:45:22 +0200 +Subject: netfilter: nf_tables: restore IP sanity checks for netdev/egress + +From: Pablo Neira Ayuso + +[ Upstream commit 5fd0628918977a0afdc2e6bc562d8751b5d3b8c5 ] + +Subtract network offset to skb->len before performing IPv4 header sanity +checks, then adjust transport offset from offset from mac header. + +Jorge Ortiz says: + +When small UDP packets (< 4 bytes payload) are sent from eth0, +`meta l4proto udp` condition is not met because `NFT_PKTINFO_L4PROTO` is +not set. This happens because there is a comparison that checks if the +transport header offset exceeds the total length. This comparison does +not take into account the fact that the skb network offset might be +non-zero in egress mode (e.g., 14 bytes for Ethernet header). + +Fixes: 0ae8e4cca787 ("netfilter: nf_tables: set transport offset from mac header for netdev/egress") +Reported-by: Jorge Ortiz +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables_ipv4.h | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h +index 60a7d0ce30804..fcf967286e37c 100644 +--- a/include/net/netfilter/nf_tables_ipv4.h ++++ b/include/net/netfilter/nf_tables_ipv4.h +@@ -19,7 +19,7 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt) + static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt) + { + struct iphdr *iph, _iph; +- u32 len, thoff; ++ u32 len, thoff, skb_len; + + iph = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb), + sizeof(*iph), &_iph); +@@ -30,8 +30,10 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt) + return -1; + + len = iph_totlen(pkt->skb, iph); +- thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4); +- if (pkt->skb->len < len) ++ thoff = iph->ihl * 4; ++ skb_len = pkt->skb->len - skb_network_offset(pkt->skb); ++ ++ if (skb_len < len) + return -1; + else if (len < thoff) + return -1; +@@ -40,7 +42,7 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt) + + pkt->flags = NFT_PKTINFO_L4PROTO; + pkt->tprot = iph->protocol; +- pkt->thoff = thoff; ++ pkt->thoff = skb_network_offset(pkt->skb) + thoff; + pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET; + + return 0; +-- +2.43.0 + diff --git a/queue-6.10/netfilter-nf_tables_ipv6-consider-network-offset-in-.patch b/queue-6.10/netfilter-nf_tables_ipv6-consider-network-offset-in-.patch new file mode 100644 index 00000000000..3eb44ffea00 --- /dev/null +++ b/queue-6.10/netfilter-nf_tables_ipv6-consider-network-offset-in-.patch @@ -0,0 +1,47 @@ +From b5eed5a81d150075985493a8b98c9676f9731c28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 15:03:23 +0200 +Subject: netfilter: nf_tables_ipv6: consider network offset in netdev/egress + validation + +From: Pablo Neira Ayuso + +[ Upstream commit 70c261d500951cf3ea0fcf32651aab9a65a91471 ] + +From netdev/egress, skb->len can include the ethernet header, therefore, +subtract network offset from skb->len when validating IPv6 packet length. + +Fixes: 42df6e1d221d ("netfilter: Introduce egress hook") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables_ipv6.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h +index 467d59b9e5334..a0633eeaec977 100644 +--- a/include/net/netfilter/nf_tables_ipv6.h ++++ b/include/net/netfilter/nf_tables_ipv6.h +@@ -31,8 +31,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt) + struct ipv6hdr *ip6h, _ip6h; + unsigned int thoff = 0; + unsigned short frag_off; ++ u32 pkt_len, skb_len; + int protohdr; +- u32 pkt_len; + + ip6h = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb), + sizeof(*ip6h), &_ip6h); +@@ -43,7 +43,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt) + return -1; + + pkt_len = ntohs(ip6h->payload_len); +- if (pkt_len + sizeof(*ip6h) > pkt->skb->len) ++ skb_len = pkt->skb->len - skb_network_offset(pkt->skb); ++ if (pkt_len + sizeof(*ip6h) > skb_len) + return -1; + + protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags); +-- +2.43.0 + diff --git a/queue-6.10/nfc-pn533-add-poll-mod-list-filling-check.patch b/queue-6.10/nfc-pn533-add-poll-mod-list-filling-check.patch new file mode 100644 index 00000000000..189c83c8e58 --- /dev/null +++ b/queue-6.10/nfc-pn533-add-poll-mod-list-filling-check.patch @@ -0,0 +1,62 @@ +From ff9434b228a3169e9d5b27a386a4a9a630d7c8c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Aug 2024 11:48:22 +0300 +Subject: nfc: pn533: Add poll mod list filling check + +From: Aleksandr Mishin + +[ Upstream commit febccb39255f9df35527b88c953b2e0deae50e53 ] + +In case of im_protocols value is 1 and tm_protocols value is 0 this +combination successfully passes the check +'if (!im_protocols && !tm_protocols)' in the nfc_start_poll(). +But then after pn533_poll_create_mod_list() call in pn533_start_poll() +poll mod list will remain empty and dev->poll_mod_count will remain 0 +which lead to division by zero. + +Normally no im protocol has value 1 in the mask, so this combination is +not expected by driver. But these protocol values actually come from +userspace via Netlink interface (NFC_CMD_START_POLL operation). So a +broken or malicious program may pass a message containing a "bad" +combination of protocol parameter values so that dev->poll_mod_count +is not incremented inside pn533_poll_create_mod_list(), thus leading +to division by zero. +Call trace looks like: +nfc_genl_start_poll() + nfc_start_poll() + ->start_poll() + pn533_start_poll() + +Add poll mod list filling check. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: dfccd0f58044 ("NFC: pn533: Add some polling entropy") +Signed-off-by: Aleksandr Mishin +Acked-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20240827084822.18785-1-amishin@t-argos.ru +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/nfc/pn533/pn533.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c +index b19c39dcfbd93..e2bc67300a915 100644 +--- a/drivers/nfc/pn533/pn533.c ++++ b/drivers/nfc/pn533/pn533.c +@@ -1723,6 +1723,11 @@ static int pn533_start_poll(struct nfc_dev *nfc_dev, + } + + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); ++ if (!dev->poll_mod_count) { ++ nfc_err(dev->dev, ++ "Poll mod list is empty\n"); ++ return -EINVAL; ++ } + + /* Do not always start polling from the same modulation */ + get_random_bytes(&rand_mod, sizeof(rand_mod)); +-- +2.43.0 + diff --git a/queue-6.10/phy-qcom-qmp-pcie-fix-x1e80100-pcie-gen4-phy-initial.patch b/queue-6.10/phy-qcom-qmp-pcie-fix-x1e80100-pcie-gen4-phy-initial.patch new file mode 100644 index 00000000000..08c842b82e6 --- /dev/null +++ b/queue-6.10/phy-qcom-qmp-pcie-fix-x1e80100-pcie-gen4-phy-initial.patch @@ -0,0 +1,99 @@ +From 56a8c335e1329ebd34527b8f89474b33742f9f44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Aug 2024 13:40:24 +0300 +Subject: phy: qcom: qmp-pcie: Fix X1E80100 PCIe Gen4 PHY initialisation + +From: Abel Vesa + +[ Upstream commit 0e8a0504da59041e775a95db3ebc1a6211423593 ] + +Update the PCIe Gen4 PHY init sequence with the latest based on internal +Qualcomm documentation. + +Fixes: 606060ce8fd0 ("phy: qcom-qmp-pcie: Add support for X1E80100 g3x2 and g4x2 PCIE") +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20240801-x1e80100-phy-qmp-pcie-fix-config-v2-1-cdc0f22b4169@linaro.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +index 8fcdcb193d241..e99cbcc378908 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +@@ -1008,8 +1008,8 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_serdes_tbl[] = { + static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RXCLK_DIV2_CTRL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_DFE_DAC_ENABLE1, 0x88), +- QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x00), +- QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x1f), ++ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH1, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_TX_ADAPT_POST_THRESH2, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B0, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B1, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MODE_RATE_0_1_B2, 0xdb), +@@ -1026,6 +1026,7 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_ln_shrd_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH4_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH5_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_MARG_COARSE_THRESH6_RATE3, 0x1f), ++ QMP_PHY_INIT_CFG(QSERDES_V6_LN_SHRD_RX_SUMMER_CAL_SPD_MODE, 0x5b), + }; + + static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_tx_tbl[] = { +@@ -1049,12 +1050,15 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_3, 0x45), +- QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0b), ++ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0a, 1), ++ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_VGA_CAL_MAN_VAL, 0x0b, 2), ++ QMP_PHY_INIT_CFG(QSERDES_V6_20_VGA_CAL_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_GM_CAL, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_EQU_ADAPTOR_CNTRL4, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_PHPRE_CTRL, 0x20), +- QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), ++ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x3a, 1), ++ QMP_PHY_INIT_CFG_LANE(QSERDES_V6_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38, 2), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x39), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B0, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE2_B1, 0xb3), +@@ -1070,6 +1074,7 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B4, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B5, 0x76), + QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff), ++ QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_TX_ADPT_CTRL, 0x10), + }; + + static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_tbl[] = { +@@ -1077,6 +1082,8 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_RX_SIGDET_LVL, 0xcc), + QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG4, 0x00), + QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_EQ_CONFIG5, 0x22), ++ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_TX_RX_CONFIG1, 0x04), ++ QMP_PHY_INIT_CFG(QPHY_V6_20_PCS_TX_RX_CONFIG2, 0x02), + }; + + static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = { +@@ -1087,11 +1094,13 @@ static const struct qmp_phy_init_tbl x1e80100_qmp_gen4x2_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG1, 0x03), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG3, 0x28), ++ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_RXEQEVAL_TIME, 0x27), ++ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_TX_RX_CONFIG, 0xc0), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_POWER_STATE_CONFIG2, 0x1d), +- QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG5, 0x0f), +- QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_FOM_EQ_CONFIG5, 0xf2), +- QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0xf2), ++ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_RX_MARGINING_CONFIG5, 0x18), ++ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G3_FOM_EQ_CONFIG5, 0x7a), ++ QMP_PHY_INIT_CFG(QPHY_PCIE_V6_20_PCS_G4_FOM_EQ_CONFIG5, 0x8a), + }; + + static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = { +-- +2.43.0 + diff --git a/queue-6.10/phy-xilinx-phy-zynqmp-fix-sgmii-linkup-failure-on-re.patch b/queue-6.10/phy-xilinx-phy-zynqmp-fix-sgmii-linkup-failure-on-re.patch new file mode 100644 index 00000000000..a643e45380e --- /dev/null +++ b/queue-6.10/phy-xilinx-phy-zynqmp-fix-sgmii-linkup-failure-on-re.patch @@ -0,0 +1,140 @@ +From debf66b78ee5479ecb7430954d689e1ea6738fe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 11:29:07 +0530 +Subject: phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume + +From: Piyush Mehta + +[ Upstream commit 5af9b304bc6010723c02f74de0bfd24ff19b1a10 ] + +On a few Kria KR260 Robotics Starter Kit the PS-GEM SGMII linkup is not +happening after the resume. This is because serdes registers are reset +when FPD is off (in suspend state) and needs to be reprogrammed in the +resume path with the same default initialization as done in the first +stage bootloader psu_init routine. + +To address the failure introduce a set of serdes registers to be saved in +the suspend path and then restore it on resume. + +Fixes: 4a33bea00314 ("phy: zynqmp: Add PHY driver for the Xilinx ZynqMP Gigabit Transceiver") +Signed-off-by: Piyush Mehta +Signed-off-by: Radhey Shyam Pandey +Link: https://lore.kernel.org/r/1722837547-2578381-1-git-send-email-radhey.shyam.pandey@amd.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/xilinx/phy-zynqmp.c | 56 +++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c +index f2bff7f25f05a..d7d12cf3011a2 100644 +--- a/drivers/phy/xilinx/phy-zynqmp.c ++++ b/drivers/phy/xilinx/phy-zynqmp.c +@@ -166,6 +166,24 @@ + /* Timeout values */ + #define TIMEOUT_US 1000 + ++/* Lane 0/1/2/3 offset */ ++#define DIG_8(n) ((0x4000 * (n)) + 0x1074) ++#define ILL13(n) ((0x4000 * (n)) + 0x1994) ++#define DIG_10(n) ((0x4000 * (n)) + 0x107c) ++#define RST_DLY(n) ((0x4000 * (n)) + 0x19a4) ++#define BYP_15(n) ((0x4000 * (n)) + 0x1038) ++#define BYP_12(n) ((0x4000 * (n)) + 0x102c) ++#define MISC3(n) ((0x4000 * (n)) + 0x19ac) ++#define EQ11(n) ((0x4000 * (n)) + 0x1978) ++ ++static u32 save_reg_address[] = { ++ /* Lane 0/1/2/3 Register */ ++ DIG_8(0), ILL13(0), DIG_10(0), RST_DLY(0), BYP_15(0), BYP_12(0), MISC3(0), EQ11(0), ++ DIG_8(1), ILL13(1), DIG_10(1), RST_DLY(1), BYP_15(1), BYP_12(1), MISC3(1), EQ11(1), ++ DIG_8(2), ILL13(2), DIG_10(2), RST_DLY(2), BYP_15(2), BYP_12(2), MISC3(2), EQ11(2), ++ DIG_8(3), ILL13(3), DIG_10(3), RST_DLY(3), BYP_15(3), BYP_12(3), MISC3(3), EQ11(3), ++}; ++ + struct xpsgtr_dev; + + /** +@@ -214,6 +232,7 @@ struct xpsgtr_phy { + * @tx_term_fix: fix for GT issue + * @saved_icm_cfg0: stored value of ICM CFG0 register + * @saved_icm_cfg1: stored value of ICM CFG1 register ++ * @saved_regs: registers to be saved/restored during suspend/resume + */ + struct xpsgtr_dev { + struct device *dev; +@@ -226,6 +245,7 @@ struct xpsgtr_dev { + bool tx_term_fix; + unsigned int saved_icm_cfg0; + unsigned int saved_icm_cfg1; ++ u32 *saved_regs; + }; + + /* +@@ -299,6 +319,32 @@ static inline void xpsgtr_clr_set_phy(struct xpsgtr_phy *gtr_phy, + writel((readl(addr) & ~clr) | set, addr); + } + ++/** ++ * xpsgtr_save_lane_regs - Saves registers on suspend ++ * @gtr_dev: pointer to phy controller context structure ++ */ ++static void xpsgtr_save_lane_regs(struct xpsgtr_dev *gtr_dev) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(save_reg_address); i++) ++ gtr_dev->saved_regs[i] = xpsgtr_read(gtr_dev, ++ save_reg_address[i]); ++} ++ ++/** ++ * xpsgtr_restore_lane_regs - Restores registers on resume ++ * @gtr_dev: pointer to phy controller context structure ++ */ ++static void xpsgtr_restore_lane_regs(struct xpsgtr_dev *gtr_dev) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(save_reg_address); i++) ++ xpsgtr_write(gtr_dev, save_reg_address[i], ++ gtr_dev->saved_regs[i]); ++} ++ + /* + * Hardware Configuration + */ +@@ -839,6 +885,8 @@ static int xpsgtr_runtime_suspend(struct device *dev) + gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); + gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + ++ xpsgtr_save_lane_regs(gtr_dev); ++ + return 0; + } + +@@ -849,6 +897,8 @@ static int xpsgtr_runtime_resume(struct device *dev) + unsigned int i; + bool skip_phy_init; + ++ xpsgtr_restore_lane_regs(gtr_dev); ++ + icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0); + icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1); + +@@ -994,6 +1044,12 @@ static int xpsgtr_probe(struct platform_device *pdev) + return ret; + } + ++ gtr_dev->saved_regs = devm_kmalloc(gtr_dev->dev, ++ sizeof(save_reg_address), ++ GFP_KERNEL); ++ if (!gtr_dev->saved_regs) ++ return -ENOMEM; ++ + return 0; + } + +-- +2.43.0 + diff --git a/queue-6.10/pktgen-use-cpus_read_lock-in-pg_net_init.patch b/queue-6.10/pktgen-use-cpus_read_lock-in-pg_net_init.patch new file mode 100644 index 00000000000..b18f3ebf842 --- /dev/null +++ b/queue-6.10/pktgen-use-cpus_read_lock-in-pg_net_init.patch @@ -0,0 +1,58 @@ +From d747dfe13cdcad62a2e282585c4ade837b461a5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 17:53:39 +0000 +Subject: pktgen: use cpus_read_lock() in pg_net_init() + +From: Eric Dumazet + +[ Upstream commit 979b581e4c69257acab1af415ddad6b2d78a2fa5 ] + +I have seen the WARN_ON(smp_processor_id() != cpu) firing +in pktgen_thread_worker() during tests. + +We must use cpus_read_lock()/cpus_read_unlock() +around the for_each_online_cpu(cpu) loop. + +While we are at it use WARN_ON_ONCE() to avoid a possible syslog flood. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20240821175339.1191779-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/pktgen.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index ea55a758a475a..197a50ef8e2e1 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -3654,7 +3654,7 @@ static int pktgen_thread_worker(void *arg) + struct pktgen_dev *pkt_dev = NULL; + int cpu = t->cpu; + +- WARN_ON(smp_processor_id() != cpu); ++ WARN_ON_ONCE(smp_processor_id() != cpu); + + init_waitqueue_head(&t->queue); + complete(&t->start_done); +@@ -3989,6 +3989,7 @@ static int __net_init pg_net_init(struct net *net) + goto remove; + } + ++ cpus_read_lock(); + for_each_online_cpu(cpu) { + int err; + +@@ -3997,6 +3998,7 @@ static int __net_init pg_net_init(struct net *net) + pr_warn("Cannot create thread for cpu %d (%d)\n", + cpu, err); + } ++ cpus_read_unlock(); + + if (list_empty(&pn->pktgen_threads)) { + pr_err("Initialization failed for all threads\n"); +-- +2.43.0 + diff --git a/queue-6.10/sctp-fix-association-labeling-in-the-duplicate-cooki.patch b/queue-6.10/sctp-fix-association-labeling-in-the-duplicate-cooki.patch new file mode 100644 index 00000000000..7f26e397787 --- /dev/null +++ b/queue-6.10/sctp-fix-association-labeling-in-the-duplicate-cooki.patch @@ -0,0 +1,96 @@ +From a425bb52312ba97f621d0815ff5c95ee731d54ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 15:07:11 +0200 +Subject: sctp: fix association labeling in the duplicate COOKIE-ECHO case + +From: Ondrej Mosnacek + +[ Upstream commit 3a0504d54b3b57f0d7bf3d9184a00c9f8887f6d7 ] + +sctp_sf_do_5_2_4_dupcook() currently calls security_sctp_assoc_request() +on new_asoc, but as it turns out, this association is always discarded +and the LSM labels never get into the final association (asoc). + +This can be reproduced by having two SCTP endpoints try to initiate an +association with each other at approximately the same time and then peel +off the association into a new socket, which exposes the unitialized +labels and triggers SELinux denials. + +Fix it by calling security_sctp_assoc_request() on asoc instead of +new_asoc. Xin Long also suggested limit calling the hook only to cases +A, B, and D, since in cases C and E the COOKIE ECHO chunk is discarded +and the association doesn't enter the ESTABLISHED state, so rectify that +as well. + +One related caveat with SELinux and peer labeling: When an SCTP +connection is set up simultaneously in this way, we will end up with an +association that is initialized with security_sctp_assoc_request() on +both sides, so the MLS component of the security context of the +association will get swapped between the peers, instead of just one side +setting it to the other's MLS component. However, at that point +security_sctp_assoc_request() had already been called on both sides in +sctp_sf_do_unexpected_init() (on a temporary association) and thus if +the exchange didn't fail before due to MLS, it won't fail now either +(most likely both endpoints have the same MLS range). + +Tested by: + - reproducer from https://src.fedoraproject.org/tests/selinux/pull-request/530 + - selinux-testsuite (https://github.com/SELinuxProject/selinux-testsuite/) + - sctp-tests (https://github.com/sctp/sctp-tests) - no tests failed + that wouldn't fail also without the patch applied + +Fixes: c081d53f97a1 ("security: pass asoc to sctp_assoc_request and sctp_sk_clone") +Suggested-by: Xin Long +Signed-off-by: Ondrej Mosnacek +Acked-by: Xin Long +Acked-by: Paul Moore (LSM/SELinux) +Link: https://patch.msgid.link/20240826130711.141271-1-omosnace@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 5adf0c0a6c1ac..7d315a18612ba 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -2260,12 +2260,6 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook( + } + } + +- /* Update socket peer label if first association. */ +- if (security_sctp_assoc_request(new_asoc, chunk->head_skb ?: chunk->skb)) { +- sctp_association_free(new_asoc); +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +- } +- + /* Set temp so that it won't be added into hashtable */ + new_asoc->temp = 1; + +@@ -2274,6 +2268,22 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook( + */ + action = sctp_tietags_compare(new_asoc, asoc); + ++ /* In cases C and E the association doesn't enter the ESTABLISHED ++ * state, so there is no need to call security_sctp_assoc_request(). ++ */ ++ switch (action) { ++ case 'A': /* Association restart. */ ++ case 'B': /* Collision case B. */ ++ case 'D': /* Collision case D. */ ++ /* Update socket peer label if first association. */ ++ if (security_sctp_assoc_request((struct sctp_association *)asoc, ++ chunk->head_skb ?: chunk->skb)) { ++ sctp_association_free(new_asoc); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ } ++ break; ++ } ++ + switch (action) { + case 'A': /* Association restart. */ + retval = sctp_sf_do_dupcook_a(net, ep, asoc, chunk, commands, +-- +2.43.0 + diff --git a/queue-6.10/selftests-forwarding-local_termination-down-ports-on.patch b/queue-6.10/selftests-forwarding-local_termination-down-ports-on.patch new file mode 100644 index 00000000000..c8024daacf8 --- /dev/null +++ b/queue-6.10/selftests-forwarding-local_termination-down-ports-on.patch @@ -0,0 +1,38 @@ +From 78ab7e3748e30a1cfc37ffb6f40660f3adb8d20c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 19:15:11 +0200 +Subject: selftests: forwarding: local_termination: Down ports on cleanup + +From: Petr Machata + +[ Upstream commit 65a3cce43d5b4c53cf16b0be1a03991f665a0806 ] + +This test neglects to put ports down on cleanup. Fix it. + +Fixes: 90b9566aa5cd ("selftests: forwarding: add a test for local_termination.sh") +Signed-off-by: Petr Machata +Link: https://patch.msgid.link/bf9b79f45de378f88344d44550f0a5052b386199.1724692132.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/local_termination.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/testing/selftests/net/forwarding/local_termination.sh b/tools/testing/selftests/net/forwarding/local_termination.sh +index 4b364cdf3ef0c..656b1a82d1dca 100755 +--- a/tools/testing/selftests/net/forwarding/local_termination.sh ++++ b/tools/testing/selftests/net/forwarding/local_termination.sh +@@ -284,6 +284,10 @@ bridge() + cleanup() + { + pre_cleanup ++ ++ ip link set $h2 down ++ ip link set $h1 down ++ + vrf_cleanup + } + +-- +2.43.0 + diff --git a/queue-6.10/selftests-forwarding-no_forwarding-down-ports-on-cle.patch b/queue-6.10/selftests-forwarding-no_forwarding-down-ports-on-cle.patch new file mode 100644 index 00000000000..5a34a257374 --- /dev/null +++ b/queue-6.10/selftests-forwarding-no_forwarding-down-ports-on-cle.patch @@ -0,0 +1,38 @@ +From 7f7df6ef40d43bb19cee9a2619e891dbd0a71d32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 18:25:37 +0200 +Subject: selftests: forwarding: no_forwarding: Down ports on cleanup + +From: Petr Machata + +[ Upstream commit e8497d6951ee8541d73784f9aac9942a7f239980 ] + +This test neglects to put ports down on cleanup. Fix it. + +Fixes: 476a4f05d9b8 ("selftests: forwarding: add a no_forwarding.sh test") +Signed-off-by: Petr Machata +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/0baf91dc24b95ae0cadfdf5db05b74888e6a228a.1724430120.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/forwarding/no_forwarding.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tools/testing/selftests/net/forwarding/no_forwarding.sh b/tools/testing/selftests/net/forwarding/no_forwarding.sh +index af3b398d13f01..9e677aa64a06a 100755 +--- a/tools/testing/selftests/net/forwarding/no_forwarding.sh ++++ b/tools/testing/selftests/net/forwarding/no_forwarding.sh +@@ -233,6 +233,9 @@ cleanup() + { + pre_cleanup + ++ ip link set dev $swp2 down ++ ip link set dev $swp1 down ++ + h2_destroy + h1_destroy + +-- +2.43.0 + diff --git a/queue-6.10/series b/queue-6.10/series index 6ffa217d9bd..1eb1c339c75 100644 --- a/queue-6.10/series +++ b/queue-6.10/series @@ -80,3 +80,35 @@ phy-fsl-imx8mq-usb-fix-tuning-parameter-name.patch soundwire-stream-fix-programming-slave-ports-for-non-continous-port-maps.patch dmaengine-dw-edma-fix-unmasking-stop-and-abort-interrupts-for-hdma.patch dmaengine-dw-edma-do-not-enable-watermark-interrupts-for-hdma.patch +phy-qcom-qmp-pcie-fix-x1e80100-pcie-gen4-phy-initial.patch +phy-xilinx-phy-zynqmp-fix-sgmii-linkup-failure-on-re.patch +dmaengine-dw-add-peripheral-bus-width-verification.patch +dmaengine-dw-add-memory-bus-width-verification.patch +dmaengine-ti-omap-dma-initialize-sglen-after-allocat.patch +pktgen-use-cpus_read_lock-in-pg_net_init.patch +cpufreq-amd-pstate-ut-don-t-check-for-highest-perf-m.patch +bluetooth-btnxpuart-handle-fw-download-abort-scenari.patch +bluetooth-btnxpuart-fix-random-crash-seen-while-remo.patch +bluetooth-hci_core-fix-not-handling-hibernation-acti.patch +iommu-do-not-return-0-from-map_pages-if-it-doesn-t-d.patch +netfilter-nf_tables-restore-ip-sanity-checks-for-net.patch +wifi-iwlwifi-mvm-take-the-mutex-before-running-link-.patch +wifi-iwlwifi-fw-fix-wgds-rev-3-exact-size.patch +wifi-iwlwifi-mvm-allow-6-ghz-channels-in-mlo-scan.patch +ethtool-check-device-is-present-when-getting-link-se.patch +hwmon-pt5161l-fix-invalid-temperature-reading.patch +net_sched-sch_fq-fix-incorrect-behavior-for-small-we.patch +netfilter-nf_tables_ipv6-consider-network-offset-in-.patch +selftests-forwarding-no_forwarding-down-ports-on-cle.patch +selftests-forwarding-local_termination-down-ports-on.patch +bonding-implement-xdo_dev_state_free-and-call-it-aft.patch +bonding-extract-the-use-of-real_device-into-local-va.patch +bonding-change-ipsec_lock-from-spin-lock-to-mutex.patch +gtp-fix-a-potential-null-pointer-dereference.patch +tcp-fix-forever-orphan-socket-caused-by-tcp_abort.patch +sctp-fix-association-labeling-in-the-duplicate-cooki.patch +drm-amd-display-avoid-using-null-object-of-framebuff.patch +net-busy-poll-use-ktime_get_ns-instead-of-local_cloc.patch +nfc-pn533-add-poll-mod-list-filling-check.patch +drm-xe-hwmon-fix-write_i1-param-from-u32-to-u16.patch +io_uring-kbuf-return-correct-iovec-count-from-classi.patch diff --git a/queue-6.10/tcp-fix-forever-orphan-socket-caused-by-tcp_abort.patch b/queue-6.10/tcp-fix-forever-orphan-socket-caused-by-tcp_abort.patch new file mode 100644 index 00000000000..6cfe441916a --- /dev/null +++ b/queue-6.10/tcp-fix-forever-orphan-socket-caused-by-tcp_abort.patch @@ -0,0 +1,99 @@ +From 0402dfd34d9050c2cf60c269ec4d2f9d6e3e4dce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 18:23:27 +0800 +Subject: tcp: fix forever orphan socket caused by tcp_abort + +From: Xueming Feng + +[ Upstream commit bac76cf89816bff06c4ec2f3df97dc34e150a1c4 ] + +We have some problem closing zero-window fin-wait-1 tcp sockets in our +environment. This patch come from the investigation. + +Previously tcp_abort only sends out reset and calls tcp_done when the +socket is not SOCK_DEAD, aka orphan. For orphan socket, it will only +purging the write queue, but not close the socket and left it to the +timer. + +While purging the write queue, tp->packets_out and sk->sk_write_queue +is cleared along the way. However tcp_retransmit_timer have early +return based on !tp->packets_out and tcp_probe_timer have early +return based on !sk->sk_write_queue. + +This caused ICSK_TIME_RETRANS and ICSK_TIME_PROBE0 not being resched +and socket not being killed by the timers, converting a zero-windowed +orphan into a forever orphan. + +This patch removes the SOCK_DEAD check in tcp_abort, making it send +reset to peer and close the socket accordingly. Preventing the +timer-less orphan from happening. + +According to Lorenzo's email in the v1 thread, the check was there to +prevent force-closing the same socket twice. That situation is handled +by testing for TCP_CLOSE inside lock, and returning -ENOENT if it is +already closed. + +The -ENOENT code comes from the associate patch Lorenzo made for +iproute2-ss; link attached below, which also conform to RFC 9293. + +At the end of the patch, tcp_write_queue_purge(sk) is removed because it +was already called in tcp_done_with_error(). + +p.s. This is the same patch with v2. Resent due to mis-labeled "changes +requested" on patchwork.kernel.org. + +Link: https://patchwork.ozlabs.org/project/netdev/patch/1450773094-7978-3-git-send-email-lorenzo@google.com/ +Fixes: c1e64e298b8c ("net: diag: Support destroying TCP sockets.") +Signed-off-by: Xueming Feng +Tested-by: Lorenzo Colitti +Reviewed-by: Jason Xing +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20240826102327.1461482-1-kuro@kuroa.me +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index ec6911034138f..2edbd5b181e29 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -4573,6 +4573,13 @@ int tcp_abort(struct sock *sk, int err) + /* Don't race with userspace socket closes such as tcp_close. */ + lock_sock(sk); + ++ /* Avoid closing the same socket twice. */ ++ if (sk->sk_state == TCP_CLOSE) { ++ if (!has_current_bpf_ctx()) ++ release_sock(sk); ++ return -ENOENT; ++ } ++ + if (sk->sk_state == TCP_LISTEN) { + tcp_set_state(sk, TCP_CLOSE); + inet_csk_listen_stop(sk); +@@ -4582,16 +4589,13 @@ int tcp_abort(struct sock *sk, int err) + local_bh_disable(); + bh_lock_sock(sk); + +- if (!sock_flag(sk, SOCK_DEAD)) { +- if (tcp_need_reset(sk->sk_state)) +- tcp_send_active_reset(sk, GFP_ATOMIC, +- SK_RST_REASON_NOT_SPECIFIED); +- tcp_done_with_error(sk, err); +- } ++ if (tcp_need_reset(sk->sk_state)) ++ tcp_send_active_reset(sk, GFP_ATOMIC, ++ SK_RST_REASON_NOT_SPECIFIED); ++ tcp_done_with_error(sk, err); + + bh_unlock_sock(sk); + local_bh_enable(); +- tcp_write_queue_purge(sk); + if (!has_current_bpf_ctx()) + release_sock(sk); + return 0; +-- +2.43.0 + diff --git a/queue-6.10/wifi-iwlwifi-fw-fix-wgds-rev-3-exact-size.patch b/queue-6.10/wifi-iwlwifi-fw-fix-wgds-rev-3-exact-size.patch new file mode 100644 index 00000000000..52d0b91f743 --- /dev/null +++ b/queue-6.10/wifi-iwlwifi-fw-fix-wgds-rev-3-exact-size.patch @@ -0,0 +1,63 @@ +From d8fc6b5cb259e70673dd6bb8f4be9005d64dd293 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Aug 2024 19:17:08 +0300 +Subject: wifi: iwlwifi: fw: fix wgds rev 3 exact size + +From: Anjaneyulu + +[ Upstream commit 3ee22f07a35b76939c5b8d17d6af292f5fafb509 ] + +Check size of WGDS revision 3 is equal to 8 entries size with some header, +but doesn't depend on the number of used entries. Check that used entries +are between min and max but allow more to be present than are used to fix +operation with some BIOSes that have such data. + +Fixes: 97f8a3d1610b ("iwlwifi: ACPI: support revision 3 WGDS tables") +Signed-off-by: Anjaneyulu +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20240825191257.cc71dfc67ec3.Ic27ee15ac6128b275c210b6de88f2145bd83ca7b@changeid +[edit commit message] +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +index fa339791223b8..ba9e656037a20 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c ++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +@@ -724,22 +724,25 @@ int iwl_acpi_get_wgds_table(struct iwl_fw_runtime *fwrt) + entry = &wifi_pkg->package.elements[entry_idx]; + entry_idx++; + if (entry->type != ACPI_TYPE_INTEGER || +- entry->integer.value > num_profiles) { ++ entry->integer.value > num_profiles || ++ entry->integer.value < ++ rev_data[idx].min_profiles) { + ret = -EINVAL; + goto out_free; + } +- num_profiles = entry->integer.value; + + /* +- * this also validates >= min_profiles since we +- * otherwise wouldn't have gotten the data when +- * looking up in ACPI ++ * Check to see if we received package count ++ * same as max # of profiles + */ + if (wifi_pkg->package.count != + hdr_size + profile_size * num_profiles) { + ret = -EINVAL; + goto out_free; + } ++ ++ /* Number of valid profiles */ ++ num_profiles = entry->integer.value; + } + goto read_table; + } +-- +2.43.0 + diff --git a/queue-6.10/wifi-iwlwifi-mvm-allow-6-ghz-channels-in-mlo-scan.patch b/queue-6.10/wifi-iwlwifi-mvm-allow-6-ghz-channels-in-mlo-scan.patch new file mode 100644 index 00000000000..9e6abc6064d --- /dev/null +++ b/queue-6.10/wifi-iwlwifi-mvm-allow-6-ghz-channels-in-mlo-scan.patch @@ -0,0 +1,51 @@ +From 0830afb7a29e9320a914f913f09ed3a6d8bc2e9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Aug 2024 19:17:12 +0300 +Subject: wifi: iwlwifi: mvm: allow 6 GHz channels in MLO scan + +From: Avraham Stern + +[ Upstream commit 454f6306a31248cf972f5f16d4c145ad5b33bfdc ] + +MLO internal scan may include 6 GHz channels. Since the 6 GHz scan +indication is not set, the channel flags are set incorrectly, which +leads to a firmware assert. +Since the MLO scan may include 6 GHz and non 6 GHz channels in one +request, add support for non-PSC 6 GHz channels (PSC channels are +already supported) when the 6 GHz indication is not set. + +Fixes: 38b3998dfba3 ("wifi: iwlwifi: mvm: Introduce internal MLO passive scan") +Signed-off-by: Avraham Stern +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20240825191257.04807f8213b2.Idd09d4366df92a74853649c1a520b7f0f752d1ac@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +index e975f5ff17b5d..7615c91a55c62 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +@@ -1659,6 +1659,17 @@ iwl_mvm_umac_scan_cfg_channels_v7(struct iwl_mvm *mvm, + cfg->v2.channel_num = channels[i]->hw_value; + if (cfg80211_channel_is_psc(channels[i])) + cfg->flags = 0; ++ ++ if (band == NL80211_BAND_6GHZ) { ++ /* 6 GHz channels should only appear in a scan request ++ * that has scan_6ghz set. The only exception is MLO ++ * scan, which has to be passive. ++ */ ++ WARN_ON_ONCE(cfg->flags != 0); ++ cfg->flags = ++ cpu_to_le32(IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE); ++ } ++ + cfg->v2.iter_count = 1; + cfg->v2.iter_interval = 0; + if (version < 17) +-- +2.43.0 + diff --git a/queue-6.10/wifi-iwlwifi-mvm-take-the-mutex-before-running-link-.patch b/queue-6.10/wifi-iwlwifi-mvm-take-the-mutex-before-running-link-.patch new file mode 100644 index 00000000000..a79d38ec55b --- /dev/null +++ b/queue-6.10/wifi-iwlwifi-mvm-take-the-mutex-before-running-link-.patch @@ -0,0 +1,47 @@ +From 710651ee3ac2c574cfc0dc74e38b3691b7dd9346 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Aug 2024 19:17:07 +0300 +Subject: wifi: iwlwifi: mvm: take the mutex before running link selection + +From: Emmanuel Grumbach + +[ Upstream commit cd6f46c2fdb82e80ca248549c1f3ebe08b4a63ab ] + +iwl_mvm_select_links is called by the link selection worker and it +requires the mutex. +Take it in the link selection worker. +This logic used to run from iwl_mvm_rx_umac_scan_complete_notif which +had the mvm->mutex held. This was changed to run in a worker holding the +wiphy mutex, but we also need the mvm->mutex. + +Fixes: 2e194efa3809 ("wifi: iwlwifi: mvm: Fix race in scan completion") +Signed-off-by: Emmanuel Grumbach +Reviewed-by: Ilan Peer +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20240825191257.0cacecd5db1e.Iaca38a078592b69bdd06549daf63408ccf1810e4@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +index d343432474db0..1380ae5155f35 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -1190,10 +1190,12 @@ static void iwl_mvm_trig_link_selection(struct wiphy *wiphy, + struct iwl_mvm *mvm = + container_of(wk, struct iwl_mvm, trig_link_selection_wk); + ++ mutex_lock(&mvm->mutex); + ieee80211_iterate_active_interfaces(mvm->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_find_link_selection_vif, + NULL); ++ mutex_unlock(&mvm->mutex); + } + + static struct iwl_op_mode * +-- +2.43.0 +