From: Greg Kroah-Hartman Date: Mon, 13 Jul 2026 13:12:02 +0000 (+0200) Subject: 6.18-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=031d5e3ef336d6a4504d83b13cab897e5bf54c95;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: binder-fix-uaf-in-binder_free_transaction.patch binder-fix-uaf-in-binder_thread_release.patch bluetooth-btusb-add-usb-id-2c4e-0128-for-mercusys-ma60xnb.patch bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch bluetooth-btusb-fix-use-after-free-on-registration-failure.patch bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch vfio-pci-fix-racy-bitfields-and-tighten-struct-layout.patch vfio-pci-latch-disable_idle_d3-per-device.patch vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch vfio-pci-use-a-private-flag-to-prevent-power-state-change-with-vfs.patch vfio-prevent-infinite-loop-in-vfio_mig_get_next_state-on-blocked-arc.patch vfio-remove-device-debugfs-before-releasing-devres.patch --- diff --git a/queue-6.18/binder-fix-uaf-in-binder_free_transaction.patch b/queue-6.18/binder-fix-uaf-in-binder_free_transaction.patch new file mode 100644 index 0000000000..cf9d3972cb --- /dev/null +++ b/queue-6.18/binder-fix-uaf-in-binder_free_transaction.patch @@ -0,0 +1,95 @@ +From f223d27a546c1e1f48d38fd67760e78f068fe8c4 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Fri, 19 Jun 2026 18:52:31 +0000 +Subject: binder: fix UAF in binder_free_transaction() + +From: Carlos Llamas + +commit f223d27a546c1e1f48d38fd67760e78f068fe8c4 upstream. + +In binder_free_transaction(), the t->to_proc is read under the t->lock. +However, once the t->lock is dropped, the to_proc can die in parallel. +This leads to a use-after-free error when we attempt to acquire its +inner lock right afterwards: + + ================================================================== + BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xe4/0x1a0 + Write of size 4 at addr ffff00001125da70 by task B/672 + + CPU: 20 UID: 0 PID: 672 Comm: B Not tainted 7.1.0-rc6-00284-g8e65320d91cd #4 PREEMPT + Hardware name: linux,dummy-virt (DT) + Call trace: + _raw_spin_lock+0xe4/0x1a0 + binder_free_transaction+0x8c/0x320 + binder_send_failed_reply+0x21c/0x2f8 + binder_thread_release+0x488/0x7e0 + binder_ioctl+0x12c0/0x29a0 + [...] + + Allocated by task 675: + __kmalloc_cache_noprof+0x174/0x444 + binder_open+0x118/0xb70 + do_dentry_open+0x374/0x1040 + vfs_open+0x58/0x3bc + [...] + + Freed by task 212: + __kasan_slab_free+0x58/0x80 + kfree+0x1a0/0x4a4 + binder_proc_dec_tmpref+0x32c/0x5e0 + binder_deferred_func+0xc48/0x104c + process_one_work+0x53c/0xbc0 + [...] + ================================================================== + +To prevent this, pin the target thread (t->to_thread) to guarantee the +target process remains alive. Undelivered transactions without a target +thread are already safe, as the target process can only be the current +context in those paths. + +Cc: stable +Reported-by: Alice Ryhl +Closes: https://lore.kernel.org/all/aikJKVuny_eOivwN@google.com/ +Fixes: a370003cc301 ("binder: fix possible UAF when freeing buffer") +Signed-off-by: Carlos Llamas +Reviewed-by: Alice Ryhl +Link: https://patch.msgid.link/20260619185233.2194678-2-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -1658,10 +1658,19 @@ static void binder_txn_latency_free(stru + + static void binder_free_transaction(struct binder_transaction *t) + { ++ struct binder_thread *target_thread; + struct binder_proc *target_proc; + + spin_lock(&t->lock); + target_proc = t->to_proc; ++ target_thread = t->to_thread; ++ /* ++ * Pin target_thread to keep target_proc alive. Undelivered ++ * transactions with !target_thread are safe, as target_proc ++ * can only be the current context there. ++ */ ++ if (target_thread) ++ atomic_inc(&target_thread->tmp_ref); + spin_unlock(&t->lock); + + if (target_proc) { +@@ -1676,6 +1685,10 @@ static void binder_free_transaction(stru + t->buffer->transaction = NULL; + binder_inner_proc_unlock(target_proc); + } ++ ++ if (target_thread) ++ binder_thread_dec_tmpref(target_thread); ++ + if (trace_binder_txn_latency_free_enabled()) + binder_txn_latency_free(t); + /* diff --git a/queue-6.18/binder-fix-uaf-in-binder_thread_release.patch b/queue-6.18/binder-fix-uaf-in-binder_thread_release.patch new file mode 100644 index 0000000000..fa98b3ff4a --- /dev/null +++ b/queue-6.18/binder-fix-uaf-in-binder_thread_release.patch @@ -0,0 +1,79 @@ +From 114a116aaa5f0295376cdf12da743c5bce3b20ce Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Fri, 19 Jun 2026 18:52:30 +0000 +Subject: binder: fix UAF in binder_thread_release() + +From: Carlos Llamas + +commit 114a116aaa5f0295376cdf12da743c5bce3b20ce upstream. + +When a thread exits, binder_thread_release() walks its transaction stack +to clear the t->from and t->to_proc that correspond with the exiting +thread. However, a process dying in parallel might attempt to kfree some +of these transactions. And if one of them has no associated t->to_proc, +the t->to_proc->inner_lock will not be acquired. + +This means that transaction accesses in binder_thread_release() after +t->to_proc has been cleared might race with binder_free_transaction() +and cause a use-after-free error as reported by KASAN: + + ================================================================== + BUG: KASAN: slab-use-after-free in binder_thread_release+0x5d0/0x798 + Write of size 8 at addr ffff000016627500 by task X/715 + + CPU: 17 UID: 0 PID: 715 Comm: X Not tainted 7.1.0-rc5-00149-g8fde5d1d47f6 #30 PREEMPT + Hardware name: linux,dummy-virt (DT) + Call trace: + binder_thread_release+0x5d0/0x798 + binder_ioctl+0x12c0/0x299c + [...] + + Allocated by task 717 on cpu 18 at 67.267803s: + __kasan_kmalloc+0xa0/0xbc + __kmalloc_cache_noprof+0x174/0x444 + binder_transaction+0x554/0x8150 + binder_thread_write+0xa30/0x4354 + binder_ioctl+0x20f0/0x299c + [...] + + Freed by task 202 on cpu 18 at 90.416221s: + __kasan_slab_free+0x58/0x80 + kfree+0x1a0/0x4a4 + binder_free_transaction+0x150/0x294 + binder_send_failed_reply+0x398/0x6d8 + binder_release_work+0x3e4/0x4ec + binder_deferred_func+0xbd8/0x104c + [...] + ================================================================== + +In order to avoid this, make sure that binder_free_transaction() reads +the t->to_proc under the transaction lock. This will serialize the +transaction release with the accesses in binder_thread_release(). Plus, +it matches the documented locking rules for @to_proc. + +Cc: stable +Fixes: 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe") +Reviewed-by: Alice Ryhl +Signed-off-by: Carlos Llamas +Link: https://patch.msgid.link/20260619185233.2194678-1-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -1658,7 +1658,11 @@ static void binder_txn_latency_free(stru + + static void binder_free_transaction(struct binder_transaction *t) + { +- struct binder_proc *target_proc = t->to_proc; ++ struct binder_proc *target_proc; ++ ++ spin_lock(&t->lock); ++ target_proc = t->to_proc; ++ spin_unlock(&t->lock); + + if (target_proc) { + binder_inner_proc_lock(target_proc); diff --git a/queue-6.18/bluetooth-btusb-add-usb-id-2c4e-0128-for-mercusys-ma60xnb.patch b/queue-6.18/bluetooth-btusb-add-usb-id-2c4e-0128-for-mercusys-ma60xnb.patch new file mode 100644 index 0000000000..6c24fe2beb --- /dev/null +++ b/queue-6.18/bluetooth-btusb-add-usb-id-2c4e-0128-for-mercusys-ma60xnb.patch @@ -0,0 +1,77 @@ +From 88b4d528eda4ac71c2952b3458f2abbc80a91cd2 Mon Sep 17 00:00:00 2001 +From: Zenm Chen +Date: Tue, 26 May 2026 00:19:42 +0800 +Subject: Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNB + +From: Zenm Chen + +commit 88b4d528eda4ac71c2952b3458f2abbc80a91cd2 upstream. + +Add USB ID 2c4e:0128 for Mercusys MA60XNB, an RTL8851BU-based +Wi-Fi + Bluetooth adapter. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below: + +T: Bus=03 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2c4e ProdID=0128 Rev= 0.00 +S: Manufacturer=Realtek +S: Product=802.11ax WLAN Adapter +S: SerialNumber=00e04c000001 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 8 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtw89_8851bu +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Cc: stable@vger.kernel.org # 6.6.x +Signed-off-by: Zenm Chen +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -531,6 +531,8 @@ static const struct usb_device_id quirks + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x2c4e, 0x0128), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8852AE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK | diff --git a/queue-6.18/bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch b/queue-6.18/bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch new file mode 100644 index 0000000000..6c4033f033 --- /dev/null +++ b/queue-6.18/bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch @@ -0,0 +1,65 @@ +From c5b600a3c05b1a7a110d558df935a8fc8a471c79 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 4 Jun 2026 08:37:37 +0200 +Subject: Bluetooth: btusb: fix use-after-free on marvell probe failure + +From: Johan Hovold + +commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 upstream. + +Make sure to stop any TX URBs submitted during Marvell OOB wakeup +configuration on later probe failures to avoid use-after-free in the +completion callback. + +This issue was reported by Sashiko while reviewing a fix for a wakeup +source leak in the btusb probe errors paths. + +Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org +Fixes: a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup") +Cc: stable@vger.kernel.org # 4.11 +Cc: Rajat Jain +Signed-off-by: Johan Hovold +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btusb.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -4193,7 +4193,7 @@ static int btusb_probe(struct usb_interf + if (id->driver_info & BTUSB_INTEL_COMBINED) { + err = btintel_configure_setup(hdev, btusb_driver.name); + if (err) +- goto out_free_dev; ++ goto err_kill_tx_urbs; + + /* Transport specific configuration */ + hdev->send = btusb_send_frame_intel; +@@ -4355,7 +4355,7 @@ static int btusb_probe(struct usb_interf + err = usb_set_interface(data->udev, 0, 0); + if (err < 0) { + BT_ERR("failed to set interface 0, alt 0 %d", err); +- goto out_free_dev; ++ goto err_kill_tx_urbs; + } + } + +@@ -4363,7 +4363,7 @@ static int btusb_probe(struct usb_interf + err = usb_driver_claim_interface(&btusb_driver, + data->isoc, data); + if (err < 0) +- goto out_free_dev; ++ goto err_kill_tx_urbs; + } + + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) { +@@ -4399,6 +4399,8 @@ err_release_siblings: + usb_set_intfdata(data->isoc, NULL); + usb_driver_release_interface(&btusb_driver, data->isoc); + } ++err_kill_tx_urbs: ++ usb_kill_anchored_urbs(&data->tx_anchor); + out_free_dev: + if (data->reset_gpio) + gpiod_put(data->reset_gpio); diff --git a/queue-6.18/bluetooth-btusb-fix-use-after-free-on-registration-failure.patch b/queue-6.18/bluetooth-btusb-fix-use-after-free-on-registration-failure.patch new file mode 100644 index 0000000000..e31142ca22 --- /dev/null +++ b/queue-6.18/bluetooth-btusb-fix-use-after-free-on-registration-failure.patch @@ -0,0 +1,55 @@ +From eedc6867ebad73edbfaf9a0a65fbef7115cc4753 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 4 Jun 2026 08:37:36 +0200 +Subject: Bluetooth: btusb: fix use-after-free on registration failure + +From: Johan Hovold + +commit eedc6867ebad73edbfaf9a0a65fbef7115cc4753 upstream. + +Make sure to release the sibling interfaces in case controller +registration fails to avoid use-after-free and double-free when they are +eventually disconnected. + +This issue was reported by Sashiko while reviewing a fix for a wakeup +source leak in the btusb probe errors paths. + +Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org +Fixes: 9bfa35fe422c ("[Bluetooth] Add SCO support to btusb driver") +Fixes: 9d08f50401ac ("Bluetooth: btusb: Add support for Broadcom LM_DIAG interface") +Cc: stable@vger.kernel.org # 2.6.27 +Reviewed-by: Paul Menzel +Signed-off-by: Johan Hovold +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btusb.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -4381,7 +4381,7 @@ static int btusb_probe(struct usb_interf + + err = hci_register_dev(hdev); + if (err < 0) +- goto out_free_dev; ++ goto err_release_siblings; + + usb_set_intfdata(intf, data); + +@@ -4390,6 +4390,15 @@ static int btusb_probe(struct usb_interf + + return 0; + ++err_release_siblings: ++ if (data->diag) { ++ usb_set_intfdata(data->diag, NULL); ++ usb_driver_release_interface(&btusb_driver, data->diag); ++ } ++ if (data->isoc) { ++ usb_set_intfdata(data->isoc, NULL); ++ usb_driver_release_interface(&btusb_driver, data->isoc); ++ } + out_free_dev: + if (data->reset_gpio) + gpiod_put(data->reset_gpio); diff --git a/queue-6.18/bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch b/queue-6.18/bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch new file mode 100644 index 0000000000..7cd6fb4c18 --- /dev/null +++ b/queue-6.18/bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch @@ -0,0 +1,78 @@ +From 3d93e1bb0fb881fe3ef961d1120556658e9cac4d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 4 Jun 2026 08:37:38 +0200 +Subject: Bluetooth: btusb: fix wakeup source leak on probe failure + +From: Johan Hovold + +commit 3d93e1bb0fb881fe3ef961d1120556658e9cac4d upstream. + +Make sure to disable wakeup on probe failure to avoid leaking the wakeup +source. + +Fixes: fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support") +Cc: stable@vger.kernel.org # 4.11 +Cc: Rajat Jain +Signed-off-by: Johan Hovold +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/btusb.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -2934,6 +2934,11 @@ static int marvell_config_oob_wake(struc + + return 0; + } ++#else ++static inline int marvell_config_oob_wake(struct hci_dev *hdev) ++{ ++ return 0; ++} + #endif + + static int btusb_set_bdaddr_marvell(struct hci_dev *hdev, +@@ -3793,6 +3798,11 @@ static int btusb_config_oob_wake(struct + bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq); + return 0; + } ++#else ++static inline int btusb_config_oob_wake(struct hci_dev *hdev) ++{ ++ return 0; ++} + #endif + + static void btusb_check_needs_reset_resume(struct usb_interface *intf) +@@ -4147,7 +4157,6 @@ static int btusb_probe(struct usb_interf + hdev->wakeup = btusb_wakeup; + hdev->hci_drv = &btusb_hci_drv; + +-#ifdef CONFIG_PM + err = btusb_config_oob_wake(hdev); + if (err) + goto out_free_dev; +@@ -4156,9 +4165,9 @@ static int btusb_probe(struct usb_interf + if (id->driver_info & BTUSB_MARVELL && data->oob_wake_irq) { + err = marvell_config_oob_wake(hdev); + if (err) +- goto out_free_dev; ++ goto err_disable_wakeup; + } +-#endif ++ + if (id->driver_info & BTUSB_CW6622) + hci_set_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY); + +@@ -4401,6 +4410,9 @@ err_release_siblings: + } + err_kill_tx_urbs: + usb_kill_anchored_urbs(&data->tx_anchor); ++err_disable_wakeup: ++ if (data->oob_wake_irq) ++ device_init_wakeup(&data->udev->dev, false); + out_free_dev: + if (data->reset_gpio) + gpiod_put(data->reset_gpio); diff --git a/queue-6.18/series b/queue-6.18/series index 28928adc13..6b86587a18 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -113,3 +113,15 @@ alsa-usb-audio-propagate-us-16x08-write-errors-in-route-mix-eq-switch-put-callba alsa-usb-audio-roll-back-quirk-control-caches-on-write-errors.patch alsa-usb-audio-update-babyface-pro-control-caches-only-after-successful-writes.patch alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patch +vfio-pci-use-a-private-flag-to-prevent-power-state-change-with-vfs.patch +vfio-pci-latch-disable_idle_d3-per-device.patch +vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch +vfio-pci-fix-racy-bitfields-and-tighten-struct-layout.patch +vfio-prevent-infinite-loop-in-vfio_mig_get_next_state-on-blocked-arc.patch +vfio-remove-device-debugfs-before-releasing-devres.patch +bluetooth-btusb-add-usb-id-2c4e-0128-for-mercusys-ma60xnb.patch +bluetooth-btusb-fix-use-after-free-on-registration-failure.patch +bluetooth-btusb-fix-use-after-free-on-marvell-probe-failure.patch +bluetooth-btusb-fix-wakeup-source-leak-on-probe-failure.patch +binder-fix-uaf-in-binder_thread_release.patch +binder-fix-uaf-in-binder_free_transaction.patch diff --git a/queue-6.18/vfio-pci-fix-racy-bitfields-and-tighten-struct-layout.patch b/queue-6.18/vfio-pci-fix-racy-bitfields-and-tighten-struct-layout.patch new file mode 100644 index 0000000000..aabe013c60 --- /dev/null +++ b/queue-6.18/vfio-pci-fix-racy-bitfields-and-tighten-struct-layout.patch @@ -0,0 +1,94 @@ +From e73638e55f861758d49f14d7bb5dba3035981cd7 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Mon, 15 Jun 2026 13:12:31 -0600 +Subject: vfio/pci: Fix racy bitfields and tighten struct layout + +From: Alex Williamson + +commit e73638e55f861758d49f14d7bb5dba3035981cd7 upstream. + +Bitfield operations are not atomic, they use a read-modify-write +pattern, therefore we should be careful not to pack bitfields that +can be concurrently updated into the same storage unit. + +This split takes a binary approach: flags that are only modified +pre/post open/close remain bitfields, flags modified from user +action, including actions that reach across to another device (ex. +reset) use dedicated storage units. + +Note that the virq_disabled and bardirty flags are relocated to fill +an existing hole in the structure. + +Bitfield justifications: + + has_dyn_msix: written only in vfio_pci_core_enable() + pci_2_3: written only in vfio_pci_core_enable() + reset_works: written only in vfio_pci_core_enable() + extended_caps: written only in vfio_cap_len() under vfio_config_init() + has_vga: written only in vfio_pci_core_enable() + nointx: written only in vfio_pci_core_enable() + needs_pm_restore: written only in vfio_pci_probe_power_state() + disable_idle_d3: written only at .init in vfio_pci_core_init_dev() + +Dedicated storage units: + + virq_disabled: written by guest INTx command writes in + vfio_basic_config_write() while the device is open + bardirty: written by guest BAR writes in vfio_basic_config_write() + while the device is open + pm_intx_masked: written in the runtime-PM suspend path. + pm_runtime_engaged: written by low-power feature entry/exit paths + needs_reset: set in vfio_pci_core_disable() and cleared for devices in + the set by vfio_pci_dev_set_try_reset() + sriov_active: written by vfio_pci_core_sriov_configure() via sysfs + sriov_numvfs while bound. + +Fixes: 9cd0f6d5cbb6 ("vfio/pci: Use bitfield for struct vfio_pci_core_device flags") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Alex Williamson +Reviewed-by: Kevin Tian +Link: https://lore.kernel.org/r/20260615191241.688297-4-alex.williamson@nvidia.com +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/vfio_pci_core.h | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/include/linux/vfio_pci_core.h ++++ b/include/linux/vfio_pci_core.h +@@ -60,6 +60,9 @@ struct vfio_pci_core_device { + struct pci_dev *pdev; + void __iomem *barmap[PCI_STD_NUM_BARS]; + bool bar_mmap_supported[PCI_STD_NUM_BARS]; ++ /* Flags modified at runtime - dedicated storage unit */ ++ bool virq_disabled; ++ bool bardirty; + u8 *pci_config_map; + u8 *vconfig; + struct perm_bits *msi_perm; +@@ -74,19 +77,19 @@ struct vfio_pci_core_device { + u16 msix_size; + u32 msix_offset; + u32 rbar[7]; ++ /* Flags only modified on setup/release - bitfield ok */ + bool has_dyn_msix:1; + bool pci_2_3:1; +- bool virq_disabled:1; + bool reset_works:1; + bool extended_caps:1; +- bool bardirty:1; + bool has_vga:1; +- bool needs_reset:1; + bool nointx:1; + bool needs_pm_restore:1; +- bool pm_intx_masked:1; +- bool pm_runtime_engaged:1; + bool disable_idle_d3:1; ++ /* Flags modified at runtime - dedicated storage unit */ ++ bool needs_reset; ++ bool pm_intx_masked; ++ bool pm_runtime_engaged; + bool sriov_active; + struct pci_saved_state *pci_saved_state; + struct pci_saved_state *pm_save; diff --git a/queue-6.18/vfio-pci-latch-disable_idle_d3-per-device.patch b/queue-6.18/vfio-pci-latch-disable_idle_d3-per-device.patch new file mode 100644 index 0000000000..56f96985d4 --- /dev/null +++ b/queue-6.18/vfio-pci-latch-disable_idle_d3-per-device.patch @@ -0,0 +1,150 @@ +From 4575e9aac5336d1365138c0284773bf8da4b1fa3 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Mon, 15 Jun 2026 13:12:29 -0600 +Subject: vfio/pci: Latch disable_idle_d3 per device + +From: Alex Williamson + +commit 4575e9aac5336d1365138c0284773bf8da4b1fa3 upstream. + +When disable_idle_d3 was introduced in vfio-pci, it directly manipulated +the device power state with pci_set_power_state(). There were no +refcounts to maintain or balanced operations, we could unconditionally +bring the device to D0 and conditionally move it to D3hot. Therefore +the module parameter was made writable. + +Later, in commit c61302aa48f7 ("vfio/pci: Move module parameters to +vfio_pci.c"), as part of the vfio-pci-core split, the writable aspect +of the module parameter was nullified. The parameter value could still +be changed through sysfs, but the vfio-pci driver latched the values +into vfio-pci-core globals at module init. Loading the vfio-pci module, +or unloading and reloading, with non-default or different values could +change the globals relative to existing devices bound to vfio-pci +variant drivers. + +Runtime PM was introduced in commit 7ab5e10eda02 ("vfio/pci: Move the +unused device into low power state with runtime PM"), which marks the +point where power states became refcounted. PM get and put operations +need to be balanced, but the same module operations noted above can +change the global variables relative to those devices already bound to +vfio-pci variant drivers. This introduces a window where PM operations +can now become unbalanced. + +To resolve this with a narrow footprint for stable backports, the +disable_idle_d3 flag is latched into the vfio_pci_core_device at the +time of initialization, such that the device always operates with a +consistent value. + +NB. vfio_pci_dev_set_try_reset() now unconditionally raises the +runtime PM usage count around bus reset to account for disable_idle_d3 +becoming a per-device rather than global flag. When this flag is set, +the additional get/put pair is harmless and allows continued use of the +shared vfio_pci_dev_set_pm_runtime_get() helper. + +Fixes: 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Alex Williamson +Reviewed-by: Kevin Tian +Link: https://lore.kernel.org/r/20260615191241.688297-2-alex.williamson@nvidia.com +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vfio/pci/vfio_pci_core.c | 19 ++++++++++--------- + include/linux/vfio_pci_core.h | 1 + + 2 files changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -506,7 +506,7 @@ int vfio_pci_core_enable(struct vfio_pci + u16 cmd; + u8 msix_pos; + +- if (!disable_idle_d3) { ++ if (!vdev->disable_idle_d3) { + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) + return ret; +@@ -584,7 +584,7 @@ out_free_state: + out_disable_device: + pci_disable_device(pdev); + out_power: +- if (!disable_idle_d3) ++ if (!vdev->disable_idle_d3) + pm_runtime_put(&pdev->dev); + return ret; + } +@@ -720,7 +720,7 @@ out: + vfio_pci_dev_set_try_reset(vdev->vdev.dev_set); + + /* Put the pm-runtime usage counter acquired during enable */ +- if (!disable_idle_d3) ++ if (!vdev->disable_idle_d3) + pm_runtime_put(&pdev->dev); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_disable); +@@ -2131,6 +2131,8 @@ int vfio_pci_core_init_dev(struct vfio_d + init_rwsem(&vdev->memory_lock); + xa_init(&vdev->ctx); + ++ vdev->disable_idle_d3 = disable_idle_d3; ++ + return 0; + } + EXPORT_SYMBOL_GPL(vfio_pci_core_init_dev); +@@ -2222,7 +2224,7 @@ int vfio_pci_core_register_device(struct + + dev->driver->pm = &vfio_pci_core_pm_ops; + pm_runtime_allow(dev); +- if (!disable_idle_d3) ++ if (!vdev->disable_idle_d3) + pm_runtime_put(dev); + + ret = vfio_register_group_dev(&vdev->vdev); +@@ -2231,7 +2233,7 @@ int vfio_pci_core_register_device(struct + return 0; + + out_power: +- if (!disable_idle_d3) ++ if (!vdev->disable_idle_d3) + pm_runtime_get_noresume(dev); + + pm_runtime_forbid(dev); +@@ -2250,7 +2252,7 @@ void vfio_pci_core_unregister_device(str + vfio_pci_vf_uninit(vdev); + vfio_pci_vga_uninit(vdev); + +- if (!disable_idle_d3) ++ if (!vdev->disable_idle_d3) + pm_runtime_get_noresume(&vdev->pdev->dev); + + pm_runtime_forbid(&vdev->pdev->dev); +@@ -2578,7 +2580,7 @@ static void vfio_pci_dev_set_try_reset(s + * state. Increment the usage count for all the devices in the dev_set + * before reset and decrement the same after reset. + */ +- if (!disable_idle_d3 && vfio_pci_dev_set_pm_runtime_get(dev_set)) ++ if (vfio_pci_dev_set_pm_runtime_get(dev_set)) + return; + + if (!pci_reset_bus(pdev)) +@@ -2588,8 +2590,7 @@ static void vfio_pci_dev_set_try_reset(s + if (reset_done) + cur->needs_reset = false; + +- if (!disable_idle_d3) +- pm_runtime_put(&cur->pdev->dev); ++ pm_runtime_put(&cur->pdev->dev); + } + } + +--- a/include/linux/vfio_pci_core.h ++++ b/include/linux/vfio_pci_core.h +@@ -86,6 +86,7 @@ struct vfio_pci_core_device { + bool needs_pm_restore:1; + bool pm_intx_masked:1; + bool pm_runtime_engaged:1; ++ bool disable_idle_d3:1; + bool sriov_active; + struct pci_saved_state *pci_saved_state; + struct pci_saved_state *pm_save; diff --git a/queue-6.18/vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch b/queue-6.18/vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch new file mode 100644 index 0000000000..e88dc693a9 --- /dev/null +++ b/queue-6.18/vfio-pci-release-the-vga-arbiter-client-on-register_device-failure.patch @@ -0,0 +1,42 @@ +From daedde7f024ecf88bc8e832ed40cf2c795f0796a Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Mon, 15 Jun 2026 13:12:30 -0600 +Subject: vfio/pci: Release the VGA arbiter client on register_device() failure + +From: Alex Williamson + +commit daedde7f024ecf88bc8e832ed40cf2c795f0796a upstream. + +The re-order in the Fixes commit below displaced vfio_pci_vga_init() as +the last failure point of what is now vfio_pci_core_register_device() +without introducing an unwind for the VGA arbiter registration. + +In current kernels this is mostly benign because vfio_pci_set_decode() +only uses pci_dev state, but the original failure path could leave a +callback with a freed vdev cookie. The stale registration also becomes +unsafe again once the callback follows drvdata to the vfio device. + +Add the required VGA unwind callout. + +Fixes: 4aeec3984ddc ("vfio/pci: Re-order vfio_pci_probe()") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Alex Williamson +Reviewed-by: Kevin Tian +Link: https://lore.kernel.org/r/20260615191241.688297-3-alex.williamson@nvidia.com +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vfio/pci/vfio_pci_core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -2237,6 +2237,7 @@ out_power: + pm_runtime_get_noresume(dev); + + pm_runtime_forbid(dev); ++ vfio_pci_vga_uninit(vdev); + out_vf: + vfio_pci_vf_uninit(vdev); + return ret; diff --git a/queue-6.18/vfio-pci-use-a-private-flag-to-prevent-power-state-change-with-vfs.patch b/queue-6.18/vfio-pci-use-a-private-flag-to-prevent-power-state-change-with-vfs.patch new file mode 100644 index 0000000000..0faceb77b8 --- /dev/null +++ b/queue-6.18/vfio-pci-use-a-private-flag-to-prevent-power-state-change-with-vfs.patch @@ -0,0 +1,216 @@ +From 40ef3edf151e184d021917a5c4c771cc0870844a Mon Sep 17 00:00:00 2001 +From: Raghavendra Rao Ananta +Date: Thu, 14 May 2026 17:34:49 +0000 +Subject: vfio/pci: Use a private flag to prevent power state change with VFs + +From: Raghavendra Rao Ananta + +commit 40ef3edf151e184d021917a5c4c771cc0870844a upstream. + +The current implementation uses pci_num_vf() while holding the +memory_lock to prevent changing the power state of a PF when +VFs are enabled. This creates a lockdep circular dependency +warning because memory_lock is held during device probing. + +[ 286.997167] ====================================================== +[ 287.003363] WARNING: possible circular locking dependency detected +[ 287.009562] 7.0.0-dbg-DEV #3 Tainted: G S +[ 287.015074] ------------------------------------------------------ +[ 287.021270] vfio_pci_sriov_/18636 is trying to acquire lock: +[ 287.026942] ff45bea2294d4968 (&vdev->memory_lock){+.+.}-{4:4}, at: +vfio_pci_core_runtime_resume+0x1f/0xa0 +[ 287.036530] +[ 287.036530] but task is already holding lock: +[ 287.042383] ff45bea3a96b8230 (&new_dev_set->lock){+.+.}-{4:4}, at: +vfio_group_fops_unl_ioctl+0x44d/0x7b0 +[ 287.051879] +[ 287.051879] which lock already depends on the new lock. +[ 287.051879] +[ 287.060070] +[ 287.060070] the existing dependency chain (in reverse order) is: +[ 287.067568] +[ 287.067568] -> #2 (&new_dev_set->lock){+.+.}-{4:4}: +[ 287.073941] __mutex_lock+0x92/0xb80 +[ 287.078058] vfio_assign_device_set+0x66/0x1b0 +[ 287.083042] vfio_pci_core_register_device+0xd1/0x2a0 +[ 287.088638] vfio_pci_probe+0xd2/0x100 +[ 287.092933] local_pci_probe_callback+0x4d/0xa0 +[ 287.098001] process_scheduled_works+0x2ca/0x680 +[ 287.103158] worker_thread+0x1e8/0x2f0 +[ 287.107452] kthread+0x10c/0x140 +[ 287.111230] ret_from_fork+0x18e/0x360 +[ 287.115519] ret_from_fork_asm+0x1a/0x30 +[ 287.119983] +[ 287.119983] -> #1 ((work_completion)(&arg.work)){+.+.}-{0:0}: +[ 287.127219] __flush_work+0x345/0x490 +[ 287.131429] pci_device_probe+0x2e3/0x490 +[ 287.135979] really_probe+0x1f9/0x4e0 +[ 287.140180] __driver_probe_device+0x77/0x100 +[ 287.145079] driver_probe_device+0x1e/0x110 +[ 287.149803] __device_attach_driver+0xe3/0x170 +[ 287.154789] bus_for_each_drv+0x125/0x150 +[ 287.159346] __device_attach+0xca/0x1a0 +[ 287.163720] device_initial_probe+0x34/0x50 +[ 287.168445] pci_bus_add_device+0x6e/0x90 +[ 287.172995] pci_iov_add_virtfn+0x3c9/0x3e0 +[ 287.177719] sriov_add_vfs+0x2c/0x60 +[ 287.181838] sriov_enable+0x306/0x4a0 +[ 287.186038] vfio_pci_core_sriov_configure+0x184/0x220 +[ 287.191715] sriov_numvfs_store+0xd9/0x1c0 +[ 287.196351] kernfs_fop_write_iter+0x13f/0x1d0 +[ 287.201338] vfs_write+0x2be/0x3b0 +[ 287.205286] ksys_write+0x73/0x100 +[ 287.209233] do_syscall_64+0x14d/0x750 +[ 287.213529] entry_SYSCALL_64_after_hwframe+0x77/0x7f +[ 287.219120] +[ 287.219120] -> #0 (&vdev->memory_lock){+.+.}-{4:4}: +[ 287.225491] __lock_acquire+0x14c6/0x2800 +[ 287.230048] lock_acquire+0xd3/0x2f0 +[ 287.234168] down_write+0x3a/0xc0 +[ 287.238019] vfio_pci_core_runtime_resume+0x1f/0xa0 +[ 287.243436] __rpm_callback+0x8c/0x310 +[ 287.247730] rpm_resume+0x529/0x6f0 +[ 287.251765] __pm_runtime_resume+0x68/0x90 +[ 287.256402] vfio_pci_core_enable+0x44/0x310 +[ 287.261216] vfio_pci_open_device+0x1c/0x80 +[ 287.265947] vfio_df_open+0x10f/0x150 +[ 287.270148] vfio_group_fops_unl_ioctl+0x4a4/0x7b0 +[ 287.275476] __se_sys_ioctl+0x71/0xc0 +[ 287.279679] do_syscall_64+0x14d/0x750 +[ 287.283975] entry_SYSCALL_64_after_hwframe+0x77/0x7f +[ 287.289559] +[ 287.289559] other info that might help us debug this: +[ 287.289559] +[ 287.297582] Chain exists of: +[ 287.297582] &vdev->memory_lock --> (work_completion)(&arg.work) +--> &new_dev_set->lock +[ 287.297582] +[ 287.310023] Possible unsafe locking scenario: +[ 287.310023] +[ 287.315961] CPU0 CPU1 +[ 287.320510] ---- ---- +[ 287.325059] lock(&new_dev_set->lock); +[ 287.328917] +lock((work_completion)(&arg.work)); +[ 287.336153] lock(&new_dev_set->lock); +[ 287.342523] lock(&vdev->memory_lock); +[ 287.346382] +[ 287.346382] *** DEADLOCK *** +[ 287.346382] +[ 287.352315] 2 locks held by vfio_pci_sriov_/18636: +[ 287.357125] #0: ff45bea208ed3e18 (&group->group_lock){+.+.}-{4:4}, +at: vfio_group_fops_unl_ioctl+0x3e3/0x7b0 +[ 287.367048] #1: ff45bea3a96b8230 (&new_dev_set->lock){+.+.}-{4:4}, +at: vfio_group_fops_unl_ioctl+0x44d/0x7b0 +[ 287.376976] +[ 287.376976] stack backtrace: +[ 287.381353] CPU: 191 UID: 0 PID: 18636 Comm: vfio_pci_sriov_ +Tainted: G S 7.0.0-dbg-DEV #3 PREEMPTLAZY +[ 287.381355] Tainted: [S]=CPU_OUT_OF_SPEC +[ 287.381356] Call Trace: +[ 287.381357] +[ 287.381358] dump_stack_lvl+0x54/0x70 +[ 287.381361] print_circular_bug+0x2e1/0x300 +[ 287.381363] check_noncircular+0xf9/0x120 +[ 287.381364] ? __lock_acquire+0x5b4/0x2800 +[ 287.381366] __lock_acquire+0x14c6/0x2800 +[ 287.381368] ? pci_mmcfg_read+0x4f/0x220 +[ 287.381370] ? pci_mmcfg_write+0x57/0x220 +[ 287.381371] ? lock_acquire+0xd3/0x2f0 +[ 287.381373] ? pci_mmcfg_write+0x57/0x220 +[ 287.381374] ? lock_release+0xef/0x360 +[ 287.381376] ? vfio_pci_core_runtime_resume+0x1f/0xa0 +[ 287.381377] lock_acquire+0xd3/0x2f0 +[ 287.381378] ? vfio_pci_core_runtime_resume+0x1f/0xa0 +[ 287.381379] ? lock_is_held_type+0x76/0x100 +[ 287.381382] down_write+0x3a/0xc0 +[ 287.381382] ? vfio_pci_core_runtime_resume+0x1f/0xa0 +[ 287.381383] vfio_pci_core_runtime_resume+0x1f/0xa0 +[ 287.381384] ? __pfx_pci_pm_runtime_resume+0x10/0x10 +[ 287.381385] __rpm_callback+0x8c/0x310 +[ 287.381386] ? ktime_get_mono_fast_ns+0x3d/0xb0 +[ 287.381389] ? __pfx_pci_pm_runtime_resume+0x10/0x10 +[ 287.381390] rpm_resume+0x529/0x6f0 +[ 287.381392] ? lock_is_held_type+0x76/0x100 +[ 287.381394] __pm_runtime_resume+0x68/0x90 +[ 287.381396] vfio_pci_core_enable+0x44/0x310 +[ 287.381398] vfio_pci_open_device+0x1c/0x80 +[ 287.381399] vfio_df_open+0x10f/0x150 +[ 287.381401] vfio_group_fops_unl_ioctl+0x4a4/0x7b0 +[ 287.381402] __se_sys_ioctl+0x71/0xc0 +[ 287.381404] do_syscall_64+0x14d/0x750 +[ 287.381405] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f +[ 287.381406] ? trace_irq_disable+0x25/0xd0 +[ 287.381409] entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Introduce a private flag 'sriov_active' in the vfio_pci_core_device +struct. This allows the driver to track the SR-IOV power state requirement +without relying on pci_num_vf() while holding the memory_lock. The lock is +now only held to set the flag and ensure the device is in D0, after which +pci_enable_sriov() can be called without the lock. + +Fixes: f4162eb1e2fc ("vfio/pci: Change the PF power state to D0 before enabling VFs") +Cc: stable@vger.kernel.org +Suggested-by: Jason Gunthorpe +Suggested-by: Alex Williamson +Signed-off-by: Raghavendra Rao Ananta +Link: https://lore.kernel.org/r/20260514173449.3282188-1-rananta@google.com +[promote bitfield to plain bool to avoid storage-unit races] +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vfio/pci/vfio_pci_core.c | 17 ++++++++++++++--- + include/linux/vfio_pci_core.h | 1 + + 2 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -271,8 +271,11 @@ int vfio_pci_set_power_state(struct vfio + int ret; + + /* Prevent changing power state for PFs with VFs enabled */ +- if (pci_num_vf(pdev) && state > PCI_D0) +- return -EBUSY; ++ if (state > PCI_D0) { ++ lockdep_assert_held_write(&vdev->memory_lock); ++ if (vdev->sriov_active) ++ return -EBUSY; ++ } + + if (vdev->needs_pm_restore) { + if (pdev->current_state < PCI_D3hot && state >= PCI_D3hot) { +@@ -2309,8 +2312,9 @@ int vfio_pci_core_sriov_configure(struct + + down_write(&vdev->memory_lock); + vfio_pci_set_power_state(vdev, PCI_D0); +- ret = pci_enable_sriov(pdev, nr_virtfn); ++ vdev->sriov_active = true; + up_write(&vdev->memory_lock); ++ ret = pci_enable_sriov(pdev, nr_virtfn); + if (ret) { + pm_runtime_put(&pdev->dev); + goto out_del; +@@ -2324,6 +2328,13 @@ int vfio_pci_core_sriov_configure(struct + } + + out_del: ++ /* ++ * Avoid taking the memory_lock intentionally. A race with a power ++ * state transition would at most result in an -EBUSY, leaving the ++ * device in PCI_D0. ++ */ ++ vdev->sriov_active = false; ++ + mutex_lock(&vfio_pci_sriov_pfs_mutex); + list_del_init(&vdev->sriov_pfs_item); + out_unlock: +--- a/include/linux/vfio_pci_core.h ++++ b/include/linux/vfio_pci_core.h +@@ -86,6 +86,7 @@ struct vfio_pci_core_device { + bool needs_pm_restore:1; + bool pm_intx_masked:1; + bool pm_runtime_engaged:1; ++ bool sriov_active; + struct pci_saved_state *pci_saved_state; + struct pci_saved_state *pm_save; + int ioeventfds_nr; diff --git a/queue-6.18/vfio-prevent-infinite-loop-in-vfio_mig_get_next_state-on-blocked-arc.patch b/queue-6.18/vfio-prevent-infinite-loop-in-vfio_mig_get_next_state-on-blocked-arc.patch new file mode 100644 index 0000000000..bf8fc30bac --- /dev/null +++ b/queue-6.18/vfio-prevent-infinite-loop-in-vfio_mig_get_next_state-on-blocked-arc.patch @@ -0,0 +1,51 @@ +From a26b499b757cfc8bbff1088bb1b844639e250893 Mon Sep 17 00:00:00 2001 +From: Junrui Luo +Date: Tue, 2 Jun 2026 16:58:48 +0800 +Subject: vfio: prevent infinite loop in vfio_mig_get_next_state() on blocked arc + +From: Junrui Luo + +commit a26b499b757cfc8bbff1088bb1b844639e250893 upstream. + +vfio_mig_get_next_state() walks vfio_from_fsm_table[] one step at a time, +looping to skip optional states the device does not support until +*next_fsm is supported. A blocked transition is encoded as +VFIO_DEVICE_STATE_ERROR, which the trailing return reports as -EINVAL. + +The skip loop does not account for the ERROR sentinel. +state_flags_table[ERROR] is ~0U and vfio_from_fsm_table[ERROR][*] is +ERROR, so once *next_fsm becomes ERROR the loop condition stays true and +*next_fsm never changes. The blocked arcs STOP_COPY -> PRE_COPY and +STOP_COPY -> PRE_COPY_P2P map to ERROR yet pass the support check on a +precopy-capable device, causing the loop to spin forever while holding +the driver state mutex. This can result in a soft lockup, and a panic +with softlockup_panic set. + +Terminate the skip loop on the ERROR sentinel so a blocked transition +falls through to the existing return and reports -EINVAL. + +Fixes: 4db52602a607 ("vfio: Extend the device migration protocol with PRE_COPY") +Reported-by: Yuhao Jiang +Cc: stable@vger.kernel.org +Signed-off-by: Junrui Luo +Reviewed-by: Kevin Tian +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/SYBPR01MB7881290BBDE79B61AE6A017FAF122@SYBPR01MB7881.ausprd01.prod.outlook.com +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vfio/vfio_main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/vfio/vfio_main.c ++++ b/drivers/vfio/vfio_main.c +@@ -846,7 +846,8 @@ int vfio_mig_get_next_state(struct vfio_ + * logical state, as per the above comment. + */ + *next_fsm = vfio_from_fsm_table[cur_fsm][new_fsm]; +- while ((state_flags_table[*next_fsm] & device->migration_flags) != ++ while (*next_fsm != VFIO_DEVICE_STATE_ERROR && ++ (state_flags_table[*next_fsm] & device->migration_flags) != + state_flags_table[*next_fsm]) + *next_fsm = vfio_from_fsm_table[*next_fsm][new_fsm]; + diff --git a/queue-6.18/vfio-remove-device-debugfs-before-releasing-devres.patch b/queue-6.18/vfio-remove-device-debugfs-before-releasing-devres.patch new file mode 100644 index 0000000000..46ec2477b2 --- /dev/null +++ b/queue-6.18/vfio-remove-device-debugfs-before-releasing-devres.patch @@ -0,0 +1,76 @@ +From dc7fe87de492ea7f33a72b78d26650b75bf37f4f Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Mon, 15 Jun 2026 14:47:00 -0600 +Subject: vfio: Remove device debugfs before releasing devres + +From: Alex Williamson + +commit dc7fe87de492ea7f33a72b78d26650b75bf37f4f upstream. + +VFIO device debugfs files created with debugfs_create_devm_seqfile() +store a devres allocated debugfs_devm_entry as inode private data. +vfio_unregister_group_dev() currently calls vfio_device_del() before +vfio_device_debugfs_exit(), but device_del() releases devres. This can +leave debugfs entries visible with stale inode private data while +unregister waits for userspace references to drain. + +Remove the per-device debugfs tree before vfio_device_del(). The debugfs +view is diagnostic only, so losing it at the start of unregister is +preferable to preserving entries whose backing storage may already have +been released. + +Complete the teardown by clearing the per-device debugfs root after +removal. This matches the global debugfs root cleanup and prevents +future users from mistaking a removed dentry for a live debugfs tree +during the remainder of unregister. + +Fixes: 2202844e4468 ("vfio/migration: Add debugfs to live migration driver") +Reported-by: Sashiko AI Review +Link: https://lore.kernel.org/r/20260615192725.6A2221F000E9@smtp.kernel.org +Cc: stable@vger.kernel.org +Cc: Longfang Liu +Assisted-by: OpenAI Codex:gpt-5 +Signed-off-by: Alex Williamson +Reviewed-by: Kevin Tian +Link: https://lore.kernel.org/r/20260615204717.735302-1-alex.williamson@nvidia.com +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vfio/debugfs.c | 1 + + drivers/vfio/vfio_main.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/vfio/debugfs.c ++++ b/drivers/vfio/debugfs.c +@@ -97,6 +97,7 @@ void vfio_device_debugfs_init(struct vfi + void vfio_device_debugfs_exit(struct vfio_device *vdev) + { + debugfs_remove_recursive(vdev->debug_root); ++ vdev->debug_root = NULL; + } + + void vfio_debugfs_create_root(void) +--- a/drivers/vfio/vfio_main.c ++++ b/drivers/vfio/vfio_main.c +@@ -396,6 +396,13 @@ void vfio_unregister_group_dev(struct vf + vfio_device_group_unregister(device); + + /* ++ * Remove debugfs before device_del(), which releases devres. Some ++ * debugfs entries are created with debugfs_create_devm_seqfile() and ++ * therefore rely on devres-managed inode private data. ++ */ ++ vfio_device_debugfs_exit(device); ++ ++ /* + * Balances vfio_device_add() in register path, also prevents + * new device opened by userspace in the cdev path. + */ +@@ -424,7 +431,6 @@ void vfio_unregister_group_dev(struct vf + } + } + +- vfio_device_debugfs_exit(device); + /* Balances vfio_device_set_group in register path */ + vfio_device_remove_group(device); + }