From 39e0f013dbe2a3267fda037cd84f8ae344282803 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Tornos Martinez Date: Mon, 5 Oct 2026 12:54:35 +0200 Subject: PCI: Add device-specific reset for Qualcomm SDX62/SDX65 modems Qualcomm SDX62/SDX65 5G modems (17cb:0308) lack working reset methods for VFIO passthrough scenarios. These devices have no FLR capability, advertise NoSoftRst+ (blocking PM reset), and have broken bus reset. Standard reset methods were already disabled for these devices by commit 6a4f64c3a3ad ("PCI: Avoid SBR for Qualcomm WCN6855/WCN7850 WiFi, SDX62/SDX65 modems") because they were not working (quirk_no_bus_reset). VFIO attempts to reset devices on every reassignment. Without a proper reset capability, these devices never successfully initialize even on first VM assignment. Add a device-specific reset method using BAR-space hardware reset registers that exist in these devices. SDX62/SDX65 modem devices use MHI SoC reset via BAR0 (sequence from MHI driver: mhi_soc_reset(), mhi_pci_reset_prepare()): - Write reset request to offset 0xb0 - Wait 2 seconds for reset completion These are true hardware reset mechanisms (not power management or firmware error recovery), providing proper device reset for VFIO scenarios, allowing to enforce isolation between successive passthrough users. Testing shows stable operation over 109 VM crash/reset cycles. Device- specific reset is position #1 in the reset hierarchy, so these Qualcomm devices will use hardware reset as their primary reset method. Signed-off-by: Jose Ignacio Tornos Martinez Signed-off-by: Bjorn Helgaas Reviewed-by: Manivannan Sadhasivam Acked-by: Alex Williamson Link: https://patch.msgid.link/20261005105436.83962-2-jtornosm@redhat.com --- drivers/pci/quirks.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index de9bbccda21f..e72af7d2c775 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4230,6 +4230,45 @@ reset_complete: return 0; } +#define MHI_SOC_RESET_REQ_OFFSET 0xb0 +#define MHI_SOC_RESET_REQ BIT(0) + +/* + * Qualcomm modem device-specific reset using MHI SoC reset via BAR0 + * register. + */ +static int reset_qualcomm_modem(struct pci_dev *pdev, bool probe) +{ + void __iomem *bar; + u16 cmd; + + if (probe) + return 0; + + if (pdev->current_state != PCI_D0) + return -EINVAL; + + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + pci_write_config_word(pdev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY); + + bar = pci_iomap(pdev, 0, 0); + if (!bar) { + pci_write_config_word(pdev, PCI_COMMAND, cmd); + return -ENODEV; + } + + iowrite32(MHI_SOC_RESET_REQ, bar + MHI_SOC_RESET_REQ_OFFSET); + ioread32(bar + MHI_SOC_RESET_REQ_OFFSET); + + /* Be sure device reset has been executed */ + msleep(2000); + + pci_iounmap(pdev, bar); + pci_write_config_word(pdev, PCI_COMMAND, cmd); + + return 0; +} + static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, reset_intel_82599_sfp_virtfn }, @@ -4245,6 +4284,7 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { reset_chelsio_generic_dev }, { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF, reset_hinic_vf_dev }, + { PCI_VENDOR_ID_QCOM, 0x0308, reset_qualcomm_modem }, /* SDX62/SDX65 modems */ { 0 } }; -- cgit v1.2.3 From 2973773a8c011d06addebfad5f18f1288fb0fb56 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Tornos Martinez Date: Mon, 5 Oct 2026 12:54:36 +0200 Subject: PCI: Add device-specific reset for Qualcomm WCN6855/WCN7850 WLAN Qualcomm WCN6855 (17cb:1103) and WCN7850 (17cb:1107) WLAN devices lack working reset methods for VFIO passthrough scenarios. These devices have no FLR capability, advertise NoSoftRst+ (blocking PM reset), and have broken bus reset. Standard reset methods were already disabled for these devices by commit 6a4f64c3a3ad ("PCI: Avoid SBR for Qualcomm WCN6855/WCN7850 WiFi, SDX62/SDX65 modems") because they were not working (quirk_no_bus_reset). Resets of this device always failed prior to this commit, so VFIO on the host could not enforce isolation between successive passthrough users. If a guest driver deinitialized the device, it may have been functional if passed through to a subsequent guest, despite the lack of isolation. Otherwise the device may have been left in an undefined state (e.g., DMA and interrupts active) and unusable. Add a device-specific reset method using BAR-space hardware reset registers that exist in these devices. WCN6855/WCN7850 WLAN devices use SoC global reset via BAR0 (sequence from ath11k/ath12k driver: ath11k_pci_soc_global_reset(), ath11k_pci_sw_reset(), ath11k_mhi_set_mhictrl_reset()): - Write/clear reset bit at offset 0x3008 - Wait for PCIe link recovery (up to 5 seconds) - Clear MHI controller SYSERR status at offset 0x38 These are true hardware reset mechanisms (not power management or firmware error recovery), providing proper device reset for VFIO scenarios. Testing shows stable operation over 100+ VM crash/reset cycles, compared to previous approaches that failed after ~30 cycles. Device-specific reset is position #1 in the reset hierarchy, so these Qualcomm devices will use hardware reset as their primary reset method. Signed-off-by: Jose Ignacio Tornos Martinez Signed-off-by: Bjorn Helgaas Reviewed-by: Manivannan Sadhasivam Acked-by: Alex Williamson Link: https://patch.msgid.link/20261005105436.83962-3-jtornosm@redhat.com --- drivers/pci/quirks.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e72af7d2c775..f90cf7793c0c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -22,6 +22,7 @@ #include /* isa_dma_bridge_buggy */ #include #include +#include #include #include #include @@ -4230,6 +4231,78 @@ reset_complete: return 0; } +#define QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET 0x3008 +#define QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET_V BIT(0) +#define QUALCOMM_WLAN_MHICTRL 0x38 +#define QUALCOMM_WLAN_MHICTRL_RESET_MASK 0x2 + +/* + * Qualcomm WLAN device-specific reset using SoC global reset via BAR0 + * registers. + */ +static int reset_qualcomm_wlan(struct pci_dev *pdev, bool probe) +{ + void __iomem *bar; + u32 val; + u16 cmd; + int ret; + + if (probe) + return 0; + + if (pdev->current_state != PCI_D0) + return -EINVAL; + + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + pci_write_config_word(pdev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY); + + bar = pci_iomap(pdev, 0, 0); + if (!bar) { + pci_write_config_word(pdev, PCI_COMMAND, cmd); + return -ENODEV; + } + + val = ioread32(bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET); + if (PCI_POSSIBLE_ERROR(val)) { + ret = -ENODEV; + goto out_restore; + } + val |= QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET_V; + iowrite32(val, bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET); + ioread32(bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET); + + msleep(10); + + val &= ~QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET_V; + iowrite32(val, bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET); + ioread32(bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET); + + msleep(10); + + ret = read_poll_timeout(ioread32, val, !PCI_POSSIBLE_ERROR(val), + 20 * USEC_PER_MSEC, 5 * USEC_PER_SEC, false, + bar + QUALCOMM_WLAN_PCIE_SOC_GLOBAL_RESET); + if (ret) { + pci_err(pdev, "PCIe link failed to recover after reset\n"); + goto out_restore; + } + + /* + * After SOC_GLOBAL_RESET, MHISTATUS may still have SYSERR bit set + * and thus need to set MHICTRL_RESET to clear SYSERR. + */ + iowrite32(QUALCOMM_WLAN_MHICTRL_RESET_MASK, bar + QUALCOMM_WLAN_MHICTRL); + ioread32(bar + QUALCOMM_WLAN_MHICTRL); + + msleep(10); + +out_restore: + pci_iounmap(pdev, bar); + pci_write_config_word(pdev, PCI_COMMAND, cmd); + + return ret; +} + #define MHI_SOC_RESET_REQ_OFFSET 0xb0 #define MHI_SOC_RESET_REQ BIT(0) @@ -4285,6 +4358,8 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF, reset_hinic_vf_dev }, { PCI_VENDOR_ID_QCOM, 0x0308, reset_qualcomm_modem }, /* SDX62/SDX65 modems */ + { PCI_VENDOR_ID_QCOM, 0x1103, reset_qualcomm_wlan }, /* WCN6855 WLAN */ + { PCI_VENDOR_ID_QCOM, 0x1107, reset_qualcomm_wlan }, /* WCN7850 WLAN */ { 0 } }; -- cgit v1.2.3 From ed3ccc190765f194254c47617a0d894307d39862 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Mon, 7 Sep 2026 10:59:18 +0200 Subject: PCI: Avoid FLR and SBR on Intel DG1 0x4905 graphics adapters DRM CI consistently reports failing device reset attempts on Intel DG1 discrete graphics adapters. Manual reproduction attempts allowed to narrow down the scope of that problem to a specific revision of that hardware, SKU 8086:4905. It has been confirmed that both reset methods claimed by the device, i.e., FLR and Secondary Bus Reset, suffer from that issue. Since consecutively failing device resets may lead to system hangs, disable both useless reset methods. A respective CI test will then be skipped instead of aborting whole CI jobs. Suggested-by: Joonas Lahtinen Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/11814 Signed-off-by: Janusz Krzysztofik Signed-off-by: Bjorn Helgaas Reviewed-by: Andi Shyti Reviewed-by: Krzysztof Karas Link: https://patch.msgid.link/20260907090249.1348552-2-janusz.krzysztofik@linux.intel.com --- drivers/pci/quirks.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f90cf7793c0c..259eeead1605 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3812,6 +3812,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0xb005, quirk_no_bus_reset); */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1164, quirk_no_bus_reset); +/* Intel DG1 0x4905 may not recover from bus reset */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4905, quirk_no_bus_reset); + static void quirk_no_pm_reset(struct pci_dev *dev) { /* @@ -5712,6 +5715,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); * AMD Neural Processing Unit 0x1502 0x17f0 * Intel 82579LM Gigabit Ethernet Controller 0x1502 * Intel 82579V Gigabit Ethernet Controller 0x1503 + * Intel DG1 Discrete Graphics Adapter 0x4905 * Mediatek MT7922 802.11ax PCI Express Wireless Network Adapter * Mediatek MT7925 802.11be PCI Express Wireless Network Adapter */ @@ -5727,6 +5731,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1502, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x17f0, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x4905, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MEDIATEK, 0x0616, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MEDIATEK, 0x7925, quirk_no_flr); -- cgit v1.2.3 From 54ca8490cedee7fa3f5612f94c551152ff4bef2a Mon Sep 17 00:00:00 2001 From: Alexander Gruhlke Date: Sun, 11 Oct 2026 21:01:44 +0200 Subject: PCI: Ignore Immediate Readiness on Samsung 990 PRO NVMe The Samsung 990 PRO [144d:a80c] advertises Immediate Readiness, so pcie_flr() doesn't wait after FLR, but the drive returns ~0 for up to 7 ms. Since commit 10baa9b4df40 ("PCI: Drop unnecessary retries when restoring BARs"), the config restore after FLR is lost, which breaks VFIO passthrough of the drive. Firmware 8B2QJXD7 responds right after FLR, but older firmware such as 1B2QJXD7 doesn't, and the firmware version isn't visible here. Ignore Immediate Readiness on this device, so pcie_flr() waits. Fixes: 10baa9b4df40 ("PCI: Drop unnecessary retries when restoring BARs") Link: https://bbs.archlinux.org/viewtopic.php?id=314833 Link: https://lore.kernel.org/r/20261010160529.27974-1-gruhlke@mailbox.org Suggested-by: Lukas Wunner Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Alexander Gruhlke Signed-off-by: Bjorn Helgaas Reviewed-by: Lukas Wunner Link: https://patch.msgid.link/20261011190145.23621-2-gruhlke@mailbox.org --- drivers/pci/quirks.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 259eeead1605..f8ff6b8102b7 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5743,6 +5743,17 @@ static void quirk_no_flr_snet(struct pci_dev *dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLIDRUN, 0x1000, quirk_no_flr_snet); +/* Samsung 990 PRO advertises Immediate Readiness, but isn't ready after FLR */ +static void quirk_no_imm_ready(struct pci_dev *dev) +{ + if (!dev->imm_ready) + return; + + pci_info(dev, "Ignoring incorrectly advertised Immediate Readiness support\n"); + dev->imm_ready = 0; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa80c, quirk_no_imm_ready); + static void quirk_no_ext_tags(struct pci_dev *pdev) { struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); -- cgit v1.2.3 From ea3f3a39c3fcea8922d3935af91c96e71df543b9 Mon Sep 17 00:00:00 2001 From: Alexander Gruhlke Date: Sun, 11 Oct 2026 21:01:45 +0200 Subject: PCI: Don't treat ~0 as ready in pci_dev_wait() with RRS SV With RRS Software Visibility, pci_dev_wait() considers a device ready as soon as reading the Vendor ID doesn't return the RRS value. Devices aren't required to respond with RRS while they aren't ready, so the read may return ~0 and pci_dev_wait() stops waiting too early. This was seen with Intel [8086:0a54] and Samsung [144d:a80c] NVMe SSDs. Also wait while the Vendor ID reads ~0. A VF's Vendor ID always reads ~0, so check its Command register instead, as is done without RRS SV. Fixes: d591f6804e7e ("PCI: Wait for device readiness with Configuration RRS") Link: https://lore.kernel.org/r/20250611101442.387378-1-hui.wang@canonical.com Suggested-by: Lukas Wunner Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Alexander Gruhlke Signed-off-by: Bjorn Helgaas Reviewed-by: Lukas Wunner Link: https://patch.msgid.link/20261011190145.23621-3-gruhlke@mailbox.org --- drivers/pci/pci.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b2879a6be5f8..d80e52421bf0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1246,9 +1246,11 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) * initialize. * * If the device is below a Root Port with Configuration RRS - * Software Visibility enabled, reading the Vendor ID returns a + * Software Visibility enabled, reading the Vendor ID may return a * special data value if the device responded with RRS. Read the - * Vendor ID until we get non-RRS status. + * Vendor ID until we get non-RRS status and something other than + * ~0. The Vendor ID of VFs reads ~0, so check their Command + * register instead. * * If there's no Root Port or Configuration RRS Software Visibility * is not enabled, the device may still respond with RRS, but @@ -1268,8 +1270,13 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) if (root && root->config_rrs_sv) { pci_read_config_dword(dev, PCI_VENDOR_ID, &id); - if (!pci_bus_rrs_vendor_id(id)) - break; + if (!pci_bus_rrs_vendor_id(id)) { + if (PCI_POSSIBLE_ERROR(id) && dev->is_virtfn) + pci_read_config_dword(dev, PCI_COMMAND, + &id); + if (!PCI_POSSIBLE_ERROR(id)) + break; + } } else { pci_read_config_dword(dev, PCI_COMMAND, &id); if (!PCI_POSSIBLE_ERROR(id)) -- cgit v1.2.3