When firmware reports PCIe Advanced Error Reporting (AER) events via ACPI
APEI GHES (ghes_handle_aer()), it allocates a snapshot buffer from
ghes_estatus_pool to store the aer_capability_regs registers before
enqueuing the error record into aer_recover_ring.
If the error record cannot be enqueued or if the dequeued record cannot be
processed, the pool memory allocated for aer_capability_regs must be released.
Otherwise, unhandled errors silently leak memory in ghes_estatus_pool,
eventually leading to pool exhaustion and breaking system-wide GHES hardware
error reporting.
This series fixes two memory leaks in PCIe AER error handling:
Patch 1: Fixes a memory leak in aer_recover_queue() when kfifo_in_spinlocked()
fails due to a buffer overflow (aer_recover_ring capacity of 16 full).
The rejected entry is immediately freed via ghes_estatus_pool_region_free().
Patch 2: Fixes a memory leak in aer_recover_work_func() when a dequeued entry
cannot be mapped to an active PCI device (pdev is NULL). Refactors the
loop so ghes_estatus_pool_region_free() is called unconditionally for
every dequeued item.
Changes in v2:
- Refactored aer_recover_work_func() to ensure ghes_estatus_pool_region_free()
is called unconditionally for every dequeued item.
- Added Patch 1 to fix related memory leak in aer_recover_queue() on kfifo
buffer overflow.
- Updated commit messages with detailed pool allocation and lifecycle explanations.
Priyank Rathod (2):
PCI/AER: Fix memory leak in aer_recover_queue() on kfifo buffer overflow
PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing
drivers/pci/pcie/aer.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
Signed-off-by: Priyank Rathod <redacted>
---
Changes in v2:
- Refactored aer_recover_work_func() to ensure ghes_estatus_pool_region_free()
is called unconditionally for every dequeued record.
- Added Patch 1 to fix related memory leak in aer_recover_queue() on kfifo
buffer overflow.
- Link to v1: https://lore.kernel.org/r/20260803183853.432459-2-rathodpriyank@google.com
---
Priyank Rathod (2):
PCI/AER: Fix memory leak in aer_recover_queue() on kfifo buffer overflow
PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing
drivers/pci/pcie/aer.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
---
base-commit: 248951ddc14de84de3910f9b13f51491a8cd91df
change-id: 20260803-b4-fix-aer-memleaks-524a1bd5e888
Best regards,
--
Priyank Rathod [off-list ref]
When ACPI APEI/GHES processes PCIe AER error records, it allocates memory
for aer_capability_regs (aer_regs) from ghes_estatus_pool and passes it
to aer_recover_queue() to be enqueued into aer_recover_ring.
If kfifo_in_spinlocked() fails due to a buffer overflow,
aer_recover_queue() logged an error message but returned without freeing
aer_regs. Because the entry was rejected and never inserted into the
queue, aer_recover_work_func() could never dequeue or free it, leaking
the allocated ghes_estatus_pool memory.
Free aer_regs via ghes_estatus_pool_region_free() when
kfifo_in_spinlocked() fails on buffer overflow.
Signed-off-by: Priyank Rathod <redacted>
---
drivers/pci/pcie/aer.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
@@ -1274,9 +1274,12 @@ void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,if(kfifo_in_spinlocked(&aer_recover_ring,&entry,1,&aer_recover_ring_lock))schedule_work(&aer_recover_work);-else+else{pr_err("buffer overflow in recovery for %04x:%02x:%02x.%x\n",domain,bus,PCI_SLOT(devfn),PCI_FUNC(devfn));+ghes_estatus_pool_region_free((unsignedlong)aer_regs,+sizeof(structaer_capability_regs));+}}EXPORT_SYMBOL_GPL(aer_recover_queue);#endif
When ACPI APEI/GHES processes PCIe AER error records, it allocates memory
for aer_capability_regs (entry.regs) from ghes_estatus_pool and queues
the entry into aer_recover_ring.
In aer_recover_work_func(), items are popped from aer_recover_ring via
kfifo_get(). If pci_get_domain_bus_and_slot() fails to find a matching
pci_dev, the code previously executed 'continue', bypassing the call to
ghes_estatus_pool_region_free(). As a result, the memory allocated for
entry.regs from ghes_estatus_pool was leaked.
Refactor aer_recover_work_func() to ensure ghes_estatus_pool_region_free()
is called unconditionally for every dequeued entry, releasing the pool
memory even when pci_dev is missing.
Signed-off-by: Priyank Rathod <redacted>
---
drivers/pci/pcie/aer.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
Hi Bjorn, Mahesh, Oliver,
Gentle ping on this 2-patch series fixing two memory leaks in PCIe AER error
handling (ghes_estatus_pool exhaustion on kfifo overflow and when pci_dev
is missing).
The series has been reviewed clean by Sashiko AI and compiles with W=1
(0 errors, 0 warnings). Could you please take a look when you have a chance?
Patchwork: https://patchwork.kernel.org/project/linux-pci/list/?series=1139683
Thanks,
Priyank