From: sashiko-bot@kernel.org
To: "Krishna Chaitanya Chundru" <krishna.chundru@oss.qualcomm.com>
Cc: linux-pci@vger.kernel.org
Subject: Re: [PATCH v3] PCI: qcom: Add register dump support for PCIe Link Down events
Date: Mon, 09 Nov 2026 20:07:16 +0000 [thread overview]
Message-ID: <sashiko-outbox-205539@kernel.org> (raw)
In-Reply-To: <20261107-regdump-v3-1-c85648af91ee@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Medium] PCI: qcom: unlocked register dump in
qcom_pcie_fill_dump_buf()
- [Medium] PCI: qcom: out-of-bounds PARF reads in
qcom_pcie_fill_dump_buf()
- [Low] PCI: qcom: PARF_INT_ALL_STATUS cleared before
qcom_pcie_dump_regs()
--
commit b30e1ed6bb64a53a1b0da2d0c7ce94bc1f80823d
Author: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
PCI: qcom: Add register dump support for PCIe Link Down events
This commit dumps key DBI, PARF, and MHI controller registers to dmesg on a
PCIe Link Down interrupt and exposes the same register dump via a per-controller
"regdump" debugfs file.
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index d903f10211c23..147aab6f4155b 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
[ ... ]
> @@ -207,11 +220,48 @@
> #define PERST_DELAY_US 1000
> #define FLUSH_TIMEOUT_US 100
>
> +/* Dump buffer size for the link-down register dump */
> +#define QCOM_PCIE_DUMP_BUF_SIZE SZ_8K
> +
> #define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
>
> #define QCOM_PCIE_LINK_SPEED_TO_BW(speed) \
> Mbps_to_icc(PCIE_SPEED2MBS_ENC(pcie_get_link_speed(speed)))
>
> +#define QCOM_PCIE_DUMP_REGS_PER_LINE 4
> +
> +static const u32 qcom_pcie_parf_dump_regs[] = {
> + PARF_LTSSM,
> + PARF_INT_ALL_STATUS,
> + PARF_SYS_CTRL,
> +};
> +
> +static const u32 qcom_pcie_ext_parf_dump_regs[] = {
> + PARF_PM_STTS,
> + PARF_PM_STTS_1,
> + PARF_INT_ALL_STATUS,
> + PARF_INT_ALL_2_STATUS,
> + PARF_CLKREQ_OVERRIDE,
> + PARF_L1SS_SLEEP_MODE_HANDLER_STATUS,
> + PARF_L1SS_SLEEP_MODE_HANDLER_CFG,
> + PARF_CORE_ERRORS,
> + PARF_LINK_DOWN_AXI_ECAM_BLOCK_STATUS,
> + PARF_STATUS,
> + PARF_SYS_CTRL,
> +};
[ ... ]
> @@ -1855,6 +1912,260 @@ static int qcom_pcie_set_max_opp(struct device *dev)
> return ret;
> }
[ ... ]
> + len += scnprintf(buf + len, buf_size - len, "\nPARF registers:\n");
> + if (pcie->cfg->has_ext_parf_regs)
> + len += qcom_pcie_dump_reg_table(pcie->parf, qcom_pcie_ext_parf_dump_regs,
> + ARRAY_SIZE(qcom_pcie_ext_parf_dump_regs),
> + buf + len, buf_size - len);
> + else
> + len += qcom_pcie_dump_reg_table(pcie->parf, qcom_pcie_parf_dump_regs,
> + ARRAY_SIZE(qcom_pcie_parf_dump_regs),
> + buf + len, buf_size - len);
[Severity: Medium]
Can dumping qcom_pcie_parf_dump_regs[] read past the end of pcie->parf on
cfg_2_1_0 platforms?
qcom_pcie_probe() now registers the "regdump" debugfs file unconditionally on
all non-firmware-managed controllers. On IP v2.1.0 platforms (apq8064 and
ipq8064), has_ext_parf_regs is false and the "parf" MMIO region is only 0x100
bytes:
arch/arm/boot/dts/qcom/qcom-apq8064.dtsi:
reg = <0x1b500000 0x1000>,
<0x1b502000 0x80>,
<0x1b600000 0x100>,
<0x0ff00000 0x100000>;
reg-names = "dbi", "elbi", "parf", "config";
Reading "regdump" on these platforms reads PARF_LTSSM (0x1b0) and
PARF_INT_ALL_STATUS (0x224) beyond the 0x100-byte mapping. Additionally,
v1.0.0 and v2.1.0 controllers report LTSSM state in ELBI_SYS_STTS rather than
PARF_LTSSM, whereas newer controllers with has_ext_parf_regs set only dump
qcom_pcie_ext_parf_dump_regs[] and omit PARF_LTSSM altogether.
[ ... ]
> + if (pcie_get_link_speed(pci->max_link_speed) == PCIE_SPEED_32_0GT) {
> + u16 rasdes_cap = dw_pcie_find_rasdes_capability(pci);
> +
> + if (rasdes_cap) {
> + int num_lanes = dw_pcie_link_get_max_link_width(pci);
> + int lane;
> +
> + for (lane = 0; lane < num_lanes; lane++) {
> + val = dw_pcie_readl_dbi(pci,
> + rasdes_cap + PCIE_RAS_DES_SD_EQ_CONTROL1);
> + val &= ~PCIE_RAS_DES_SD_EQ_CONTROL1_LANE_SEL;
> + val |= lane & PCIE_RAS_DES_SD_EQ_CONTROL1_LANE_SEL;
> + dw_pcie_writel_dbi(pci,
> + rasdes_cap + PCIE_RAS_DES_SD_EQ_CONTROL1,
> + val);
> +
> + val = dw_pcie_readl_dbi(pci,
> + rasdes_cap + PCIE_RAS_DES_SD_EQ_STATUS2);
> + len += qcom_pcie_dump_lane_reg_val(buf + len, buf_size - len, &col,
> + lane,
> + rasdes_cap + PCIE_RAS_DES_SD_EQ_STATUS2,
> + val);
> +
> + val = dw_pcie_readl_dbi(pci,
> + rasdes_cap + PCIE_RAS_DES_SD_EQ_STATUS3);
> + len += qcom_pcie_dump_lane_reg_val(buf + len, buf_size - len, &col,
> + lane,
> + rasdes_cap + PCIE_RAS_DES_SD_EQ_STATUS3,
> + val);
> + }
> + }
> + }
[ ... ]
> +static int qcom_pcie_regdump_show(struct seq_file *s, void *data)
> +{
> + struct qcom_pcie *pcie = (struct qcom_pcie *)dev_get_drvdata(s->private);
> + char *buf;
> + size_t len;
> +
> + buf = kmalloc(QCOM_PCIE_DUMP_BUF_SIZE, GFP_KERNEL);
> + if (!buf)
> + return -ENOMEM;
> +
> + len = qcom_pcie_fill_dump_buf(pcie, buf, QCOM_PCIE_DUMP_BUF_SIZE);
> + seq_write(s, buf, len);
> +
> + kfree(buf);
> +
> + return 0;
> +}
[Severity: Medium]
Can qcom_pcie_fill_dump_buf() access unclocked MMIO registers if it races with
qcom_pcie_reset_root_port()?
Neither qcom_pcie_regdump_show() nor qcom_pcie_dump_regs() holds
pcie->reset_lock while calling qcom_pcie_fill_dump_buf():
CPU0 CPU1
qcom_pcie_reset_root_port() qcom_pcie_regdump_show()
guard(mutex)(&pcie->reset_lock)
qcom_pcie_host_deinit()
pcie->cfg->ops->deinit()
clk_bulk_disable_unprepare()
regulator_bulk_disable()
qcom_pcie_fill_dump_buf()
dw_pcie_readl_dbi()
<-- unclocked MMIO / SError
While qcom_pcie_reset_root_port() reinitializes the Root Port under
pcie->reset_lock, controller clocks and regulators are disabled and resets are
asserted, so concurrent DBI, PARF, or MHI reads and writes from
qcom_pcie_fill_dump_buf() can trigger an immediate bus abort (SError) and
kernel panic. In addition, on 32 GT/s controllers, concurrent callers of
qcom_pcie_fill_dump_buf() can interleave writes to the banked lane selector
PCIE_RAS_DES_SD_EQ_CONTROL1 and read back PCIE_RAS_DES_SD_EQ_STATUS2/3 for the
wrong lane.
Acquiring pcie->reset_lock around the register accesses in both dump paths
would serialize them against Root Port resets and each other.
[ ... ]
> @@ -1983,6 +2297,8 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
> qcom_pcie_enable_outbound_blocker(pcie);
> mutex_unlock(&pcie->reset_lock);
>
> + qcom_pcie_dump_regs(pcie);
> +
> for_each_pci_bridge(port, pp->bridge->bus) {
> if (pci_pcie_type(port) == PCI_EXP_TYPE_ROOT_PORT)
> pci_host_handle_link_down(port);
[Severity: Low]
Does qcom_pcie_dump_regs() read PARF_INT_ALL_STATUS after it has already been
cleared?
At the start of qcom_pcie_global_irq_thread(), the handler reads
PARF_INT_ALL_STATUS into status and immediately writes status to
PARF_INT_ALL_CLEAR:
drivers/pci/controller/dwc/pcie-qcom.c:qcom_pcie_global_irq_thread() {
unsigned long status = readl_relaxed(pcie->parf + PARF_INT_ALL_STATUS);
writel_relaxed(status, pcie->parf + PARF_INT_ALL_CLEAR);
...
}
When qcom_pcie_dump_regs() later dumps PARF_INT_ALL_STATUS from
qcom_pcie_parf_dump_regs[] or qcom_pcie_ext_parf_dump_regs[], the interrupt
status bits that triggered the Link Down event have already been cleared in
hardware.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261107-regdump-v3-1-c85648af91ee@oss.qualcomm.com?part=1
prev parent reply other threads:[~2026-11-09 20:07 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 2:27 [PATCH v3] PCI: qcom: Add register dump support for PCIe Link Down events Krishna Chaitanya Chundru
2026-11-09 20:07 ` sashiko-bot [this message]
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=sashiko-outbox-205539@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=krishna.chundru@oss.qualcomm.com \
--cc=linux-pci@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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