From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
To: bhelgaas@google.com, alex@shazbot.org
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Subject: [PATCH v2] PCI: Force PM reset for Qualcomm devices with NoSoftRst+
Date: Fri, 8 May 2026 16:51:53 +0200 [thread overview]
Message-ID: <20260508145153.717641-2-jtornosm@redhat.com> (raw)
In-Reply-To: <20260508145153.717641-1-jtornosm@redhat.com>
Some Qualcomm PCIe devices lack FLR capability and have the NoSoftRst+
flag set in their PM capability. This causes all standard PCI reset
methods to return -ENOTTY, leaving the device without any reset capability.
Add PCI_DEV_FLAGS_FORCE_PM_RESET flag to bypass the NoSoftRst check and
allow PM reset to proceed with the standard D3hot->D0 transition. This
provides these devices with a working reset method.
Apply this quirk to Qualcomm devices that need PM reset:
- ath11k WiFi (17cb:1103) - No FLR, NoSoftRst+, needs reset for reuse
- ath12k WiFi (17cb:1107) - No FLR, NoSoftRst+, needs reset for reuse
- SDX62/SDX65 5G modems (17cb:0308) - No FLR, NoSoftRst+, never initialize
without proper reset (both modem generations share the same PCI device ID)
The problem manifests in VFIO passthrough scenarios:
1. WiFi devices (ath11k, ath12k): Normal VM operation works fine,
including clean shutdown/reboot. However, when the VM terminates
uncleanly (crash, force-off), VFIO attempts to reset the device.
Without a working reset method, the device cannot be reused for
another VM, preventing device reassignment.
2. Modem devices (SDX62/SDX65): Never successfully initialize even on
first VM assignment without proper reset capability.
Testing showed that without this quirk, no reset is performed during
VFIO device initialization. With this quirk, PM reset succeeds and
devices work reliably in VFIO passthrough scenarios.
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v2:
- Split from original combined patch based on maintainer feedback (Alex
Williamson) and commented results.
- Change approach: instead of custom D3cold reset method, enable existing
pci_pm_reset() by bypassing NoSoftRst check for affected devices
(PCI_DEV_FLAGS_FORCE_PM_RESET flag is added for that)
v1: https://lore.kernel.org/all/20260507142916.392983-1-jtornosm@redhat.com/
drivers/pci/pci.c | 12 +++++++++---
drivers/pci/quirks.c | 13 +++++++++++++
include/linux/pci.h | 2 ++
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8f7cfcc00090..e0b32eccfcf4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4451,6 +4451,10 @@ static int pci_af_flr(struct pci_dev *dev, bool probe)
* cooldown period, which for the D0->D3hot and D3hot->D0 transitions is 10 ms
* by default (i.e. unless the @dev's d3hot_delay field has a different value).
* Moreover, only devices in D0 can be reset by this function.
+ *
+ * Some devices incorrectly advertise PCI_PM_CTRL_NO_SOFT_RESET but PM reset
+ * actually works. For such devices, PCI_DEV_FLAGS_FORCE_PM_RESET can be set
+ * via quirk to bypass the NO_SOFT_RESET check and enable PM reset.
*/
static int pci_pm_reset(struct pci_dev *dev, bool probe)
{
@@ -4460,9 +4464,11 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
if (!dev->pm_cap || dev->dev_flags & PCI_DEV_FLAGS_NO_PM_RESET)
return -ENOTTY;
- pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
- if (csr & PCI_PM_CTRL_NO_SOFT_RESET)
- return -ENOTTY;
+ if (!(dev->dev_flags & PCI_DEV_FLAGS_FORCE_PM_RESET)) {
+ pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
+ if (csr & PCI_PM_CTRL_NO_SOFT_RESET)
+ return -ENOTTY;
+ }
if (probe)
return 0;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index caaed1a01dc0..5e8b310c9d5f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -5595,6 +5595,19 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap);
+/*
+ * Some devices incorrectly advertise NoSoftRst+ (suggesting PM reset won't
+ * work), but PM reset via D3hot->D0 transition actually works fine. Force
+ * PM reset for these devices to provide working reset capability.
+ */
+static void quirk_force_pm_reset(struct pci_dev *dev)
+{
+ dev->dev_flags |= PCI_DEV_FLAGS_FORCE_PM_RESET;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1103, quirk_force_pm_reset); /* ath11k */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1107, quirk_force_pm_reset); /* ath12k */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0308, quirk_force_pm_reset); /* SDX62/SDX65 */
+
/*
* FLR may cause the following to devices to hang:
*
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..714dbdaa21af 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -261,6 +261,8 @@ enum pci_dev_flags {
* integrated with the downstream devices and doesn't use real PCI.
*/
PCI_DEV_FLAGS_PCI_BRIDGE_NO_ALIAS = (__force pci_dev_flags_t) (1 << 14),
+ /* Force PM reset even when NoSoftRst+ is set */
+ PCI_DEV_FLAGS_FORCE_PM_RESET = (__force pci_dev_flags_t) (1 << 15),
};
enum pci_irq_reroute_variant {
--
2.53.0
next prev parent reply other threads:[~2026-05-08 14:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-08 14:51 [PATCH v2] PCI: Disable broken FLR on MediaTek MT7925 Jose Ignacio Tornos Martinez
2026-05-08 14:51 ` Jose Ignacio Tornos Martinez [this message]
2026-05-08 17:16 ` [PATCH v2] PCI: Force PM reset for Qualcomm devices with NoSoftRst+ Alex Williamson
2026-05-08 21:21 ` sashiko-bot
2026-05-08 21:22 ` [PATCH v2] PCI: Disable broken FLR on MediaTek MT7925 sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260508145153.717641-2-jtornosm@redhat.com \
--to=jtornosm@redhat.com \
--cc=alex@shazbot.org \
--cc=bhelgaas@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox