From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>,
Thomas Gleixner <tglx@kernel.org>,
Sasha Levin <sashal@kernel.org>,
bhelgaas@google.com, jgross@suse.com, wangruikang@iscas.ac.cn,
hans.zhang@cixtech.com, roger.pau@citrix.com
Subject: [PATCH AUTOSEL 6.19-6.1] PCI/MSI: Unmap MSI-X region on error
Date: Wed, 11 Feb 2026 20:09:45 -0500 [thread overview]
Message-ID: <20260212010955.3480391-22-sashal@kernel.org> (raw)
In-Reply-To: <20260212010955.3480391-1-sashal@kernel.org>
From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
[ Upstream commit 1a8d4c6ecb4c81261bcdf13556abd4a958eca202 ]
msix_capability_init() fails to unmap the MSI-X region if
msix_setup_interrupts() fails.
Add the missing iounmap() for that error path.
[ tglx: Massaged change log ]
Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260125144452.2103812-1-lihaoxiang@isrc.iscas.ac.cn
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The bug is clearly present in v6.1, v6.6, and v6.12. In these versions,
the function structure is nearly identical to mainline — the same
missing `iounmap()` on the `msix_setup_interrupts()` error path exists.
The patch should apply cleanly (or with trivial context adjustments for
the `msix_mask_all` conditional in mainline vs unconditional in older
stable trees).
---
## Complete Analysis
### 1. COMMIT MESSAGE ANALYSIS
The commit message is clear, concise, and directly describes a resource
leak bug: `msix_capability_init()` fails to `iounmap()` the MSI-X table
region if `msix_setup_interrupts()` fails. Thomas Gleixner (the irq
subsystem maintainer) massaged the changelog and signed off as the
subsystem maintainer applying the patch. The `Link:` tag points to the
mailing list submission.
### 2. CODE CHANGE ANALYSIS
The fix is surgical — just 3 lines of net new code:
1. Changes the `goto out_disable` to `goto out_unmap` (line 740) when
`msix_setup_interrupts()` fails
2. Adds a new `out_unmap:` label with `iounmap(dev->msix_base)` just
before the existing `out_disable:` label
**The bug mechanism:** `msix_map_region()` (line 732) calls `ioremap()`
to map the MSI-X table into kernel virtual address space and stores the
result in `dev->msix_base`. If `msix_setup_interrupts()` then fails
(line 738-740), the error path goes to `out_disable` which only resets
`dev->msix_enabled` and the PCI MSI-X control register — it never calls
`iounmap()` on `dev->msix_base`.
**Why it's not cleaned up elsewhere:** The caller
`__pci_enable_msix_range()` simply returns the error code — there's no
cleanup for the ioremap'd region. The only function that calls
`iounmap(dev->msix_base)` is `pci_free_msi_irqs()`, which is only called
from `pci_disable_msix()` and `pci_disable_msi()` — but those are never
called on the failed init path.
**When the error occurs:** `msix_setup_interrupts()` can fail for
multiple practical reasons:
- `msix_setup_msi_descs()` fails (memory allocation for MSI descriptors)
- `pci_msi_setup_msi_irqs()` fails (no available IRQ vectors, domain
allocation failure)
- `msi_verify_entries()` fails (device restrictions not honored)
### 3. BUG ORIGIN
The bug was introduced by commit `438553958ba192` ("PCI/MSI: Enable and
mask MSI-X early") which was merged in v5.14-rc6. Ironically, that
commit has `Cc: stable@vger.kernel.org`, so it was backported to older
stable trees, bringing this leak bug with it.
### 4. AFFECTED STABLE TREES
I verified the bug exists in v5.15, v6.1, v6.6, and v6.12 — all
currently maintained stable trees. The code structure is nearly
identical across all of them:
- **v6.6, v6.12**: Uses `dev->msix_base = msix_map_region()` directly —
identical structure to mainline.
- **v6.1**: Uses local `base` then `dev->msix_base = base` — same bug,
same missing iounmap.
- **v5.15**: Uses local `base` variable with the same missing iounmap —
will need minor adaptation.
### 5. SCOPE AND RISK ASSESSMENT
- **Lines changed:** 3 net additions (new goto label, iounmap call,
changed goto target)
- **Files changed:** 1 (`drivers/pci/msi/msi.c`)
- **Risk:** Extremely low. The fix only adds cleanup on an error path.
It cannot affect the success path at all.
- **Subsystem:** PCI MSI-X — core PCI infrastructure used by virtually
every modern PCI device driver
### 6. USER IMPACT
The resource leak (ioremap virtual address space leak) occurs every time
MSI-X setup fails and the driver retries or the device is reprobed. In
hot-plug scenarios or with drivers that unbind/rebind (e.g., VFIO
passthrough, driver reloading), this could compound over time. While not
a crash or security issue, it's a real resource leak in a core subsystem
path that can lead to eventual `ioremap()` failures.
### 7. STABILITY INDICATORS
- Authored by a contributor who has multiple accepted fixes for similar
resource leaks in the kernel
- Applied and changelog massaged by Thomas Gleixner (irq subsystem
maintainer)
- The fix pattern (adding iounmap on error path) is a textbook leak fix
with zero ambiguity
### 8. CLASSIFICATION
This is a **resource leak fix** — a missing `iounmap()` on an error
path. It fixes a real bug, is small and contained, introduces no new
features or APIs, and follows the standard kernel error handling
pattern.
The fix is small, surgical, obviously correct, and meets all stable
kernel criteria. It fixes a genuine resource leak in core PCI MSI-X
initialization that affects all currently maintained stable trees.
**YES**
drivers/pci/msi/msi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
index 34d664139f48f..e010ecd9f90dd 100644
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -737,7 +737,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
ret = msix_setup_interrupts(dev, entries, nvec, affd);
if (ret)
- goto out_disable;
+ goto out_unmap;
/* Disable INTX */
pci_intx_for_msi(dev, 0);
@@ -758,6 +758,8 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
pcibios_free_irq(dev);
return 0;
+out_unmap:
+ iounmap(dev->msix_base);
out_disable:
dev->msix_enabled = 0;
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE, 0);
--
2.51.0
next prev parent reply other threads:[~2026-02-12 1:10 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 1:09 [PATCH AUTOSEL 6.19-5.10] clocksource/drivers/sh_tmu: Always leave device running after probe Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] gendwarfksyms: Fix build on 32-bit hosts Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] arm64/ftrace,bpf: Fix partial regs after bpf_prog_run Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] bpftool: Fix dependencies for static build Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.12] perf/x86/msr: Add Airmont NP Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] genirq/cpuhotplug: Notify about affinity changes breaking the affinity mask Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-5.15] char: tpm: cr50: Remove IRQF_ONESHOT Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.6] crypto: hisilicon/qm - move the barrier before writing to the mailbox register Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.12] sched/debug: Fix updating of ppos on server write ops Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] perf/x86/intel: Add Airmont NP Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] bpf: Properly mark live registers for indirect jumps Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-5.10] mailbox: bcm-ferxrm-mailbox: Use default primary handler Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] perf/core: Fix slow perf_event_task_exit() with LBR callstacks Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.12] perf/x86/cstate: Add Airmont NP Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-5.10] clocksource/drivers/timer-integrator-ap: Add missing Kconfig dependency on OF Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-5.10] bpf: verifier improvement in 32bit shift sign extension pattern Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.12] bpf: Recognize special arithmetic shift in the verifier Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.12] bpf: crypto: Use the correct destructor kfunc type Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-5.10] pstore: ram_core: fix incorrect success return when vmap() fails Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] bpf: net_sched: Use the correct destructor kfunc type Sasha Levin
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] irqchip/riscv-imsic: Add a CPU pm notifier to restore the IMSIC on exit Sasha Levin
2026-02-12 1:09 ` Sasha Levin [this message]
2026-02-12 1:09 ` [PATCH AUTOSEL 6.19-6.18] rust: sync: Implement Unpin for ARef Sasha Levin
2026-02-12 12:11 ` Miguel Ojeda
2026-02-26 13:45 ` Sasha Levin
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=20260212010955.3480391-22-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=bhelgaas@google.com \
--cc=hans.zhang@cixtech.com \
--cc=jgross@suse.com \
--cc=lihaoxiang@isrc.iscas.ac.cn \
--cc=patches@lists.linux.dev \
--cc=roger.pau@citrix.com \
--cc=stable@vger.kernel.org \
--cc=tglx@kernel.org \
--cc=wangruikang@iscas.ac.cn \
/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