mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ACPI: extlog: Avoid populating software AER metadata from raw hardware buffer
extlog_print_pcie() casts pcie_err->aer_info straight to struct
aer_capability_regs *. That struct embeds struct pcie_tlp_log, whose
software-only header_len and flit fields sit at offset 84 - inside the
96-byte aer_info buffer - so the cast fills them with raw firmware bytes.
pcie_print_tlp_log() uses both to bound a loop over dw[], and a large
header_len walks past the end of the array.
Copy into a zeroed local struct, and only as far as aer_info maps onto it:
the leading registers and the four Header Log DWORDs. Place the TLP Prefix
Log separately, from the offset the hardware keeps it at. The rest stays
zero, which covers header_len and flit and keeps the Root Error registers
out of the prefix log, where pcie_print_tlp_log() would print them as
end-to-end prefixes.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-cxl/20260709165457.8BA181F000E9@smtp.kernel.org/
Fixes: e778ffefa3 ("ACPI: extlog: Trace CPER PCI Express Error Section")
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260904172337.1409775-6-dave.jiang@intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
179ef6d7f9
commit
31333d134a
|
|
@ -137,7 +137,7 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
|
|||
int severity)
|
||||
{
|
||||
#ifdef ACPI_APEI_PCIEAER
|
||||
struct aer_capability_regs *aer;
|
||||
struct aer_capability_regs aer_regs = {};
|
||||
struct pci_dev *pdev;
|
||||
unsigned int devfn;
|
||||
unsigned int bus;
|
||||
|
|
@ -149,7 +149,21 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
|
|||
return;
|
||||
|
||||
aer_severity = cper_severity_to_aer(severity);
|
||||
aer = (struct aer_capability_regs *)pcie_err->aer_info;
|
||||
|
||||
/*
|
||||
* struct pcie_tlp_log is larger than the hardware layout, so aer_info
|
||||
* only maps onto the struct up to the four Header Log DWORDs. Copy that
|
||||
* much, then place the TLP Prefix Log from where the hardware keeps it.
|
||||
* Everything else stays zero: nothing reads root_command, root_status or
|
||||
* the error source IDs, and header_len and flit are software-only.
|
||||
*/
|
||||
memcpy(&aer_regs, pcie_err->aer_info,
|
||||
offsetof(struct aer_capability_regs, header_log) +
|
||||
PCIE_STD_NUM_TLP_HEADERLOG * sizeof(u32));
|
||||
memcpy(aer_regs.header_log.prefix,
|
||||
pcie_err->aer_info + PCI_ERR_PREFIX_LOG,
|
||||
sizeof(aer_regs.header_log.prefix));
|
||||
|
||||
domain = pcie_err->device_id.segment;
|
||||
bus = pcie_err->device_id.bus;
|
||||
devfn = PCI_DEVFN(pcie_err->device_id.device,
|
||||
|
|
@ -158,7 +172,7 @@ static void extlog_print_pcie(struct cper_sec_pcie *pcie_err,
|
|||
if (!pdev)
|
||||
return;
|
||||
|
||||
pci_print_aer(pdev, aer_severity, aer);
|
||||
pci_print_aer(pdev, aer_severity, &aer_regs);
|
||||
pci_dev_put(pdev);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user