[PATCH 4/4] platform/x86/amd/pmc: Validate S2D physical address before ioremap
Mario Limonciello <[email protected]>
| Newsgroups | org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
amd_stb_s2d_init() retrieves the S2D telemetry buffer's physical address via two SMU commands (low and high 32 bits) but does not check their return values. On some platforms the SMU refuses these commands (observed: "SMU cmd failed. err: 0xff") and the phys_addr_low/high output parameters are left uninitialized at zero. The driver then attempts devm_ioremap(dev, 0x0, 16 MB), which trips the ioremap-on-RAM warning and fails: amd_pmc AMDI000B:00: SMU cmd failed. err: 0xff ioremap on RAM at 0x0000000000000000 - 0x0000000000ffffff WARNING: CPU: 13 PID: 4592 at arch/x86/mm/ioremap.c:216 __ioremap_caller+0xfc/0x3b0 devm_ioremap+0x5a/0xb0 amd_stb_s2d_init+0x239/0x280 [amd_pmc] amd_pmc AMDI000B:00: STB initialization failed (-12), continuing... Probe completes successfully but the kernel is tainted by the WARN. Check both physical-address command return codes and reject a zero address before attempting the ioremap. Assisted-by: Claude:opus Signed-off-by: Mario Limonciello <[email protected]> --- drivers/platform/x86/amd/pmc/mp1_stb.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/amd/pmc/mp1_stb.c b/drivers/platform/x86/amd/pmc/mp1_stb.c index 6a048cb2605ec..a507444a945ae 100644 --- a/drivers/platform/x86/amd/pmc/mp1_stb.c +++ b/drivers/platform/x86/amd/pmc/mp1_stb.c @@ -320,10 +320,21 @@ int amd_stb_s2d_init(struct amd_pmc_dev *dev) dev->dram_size = S2D_TELEMETRY_DRAMBYTES_MAX; /* Get STB DRAM address */ - amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, dev->stb_arg.s2d_msg_id, true); - amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, dev->stb_arg.s2d_msg_id, true); + ret = amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, + dev->stb_arg.s2d_msg_id, true); + if (ret) + goto out; + ret = amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, + dev->stb_arg.s2d_msg_id, true); + if (ret) + goto out; stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low); + if (!stb_phys_addr) { + dev_err(dev->dev, "S2D phys addr query returned invalid address\n"); + ret = -ENXIO; + goto out; + } dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, dev->dram_size); if (!dev->stb_virt_addr) -- 2.43.0