From: "Shang song (Lenovo)" shangsong2@foxmail.com
[ Upstream commit 311942ce763e21dacef7e53996d5a1e19b8adab1 ]
If handler_address or mapped VA is NULL, the related buffer address and VA can be ignored, so make acpi_parse_prmt() skip the current handler in those cases.
Signed-off-by: Shang song (Lenovo) shangsong2@foxmail.com Link: https://patch.msgid.link/20250826030229.834901-1-shangsong2@foxmail.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## **Backport Status: YES**
### Extensive Analysis
#### **Commit Context and Subsystem History**
This commit is part of a series of fixes and improvements to the ACPI PRM (Platform Runtime Mechanism) subsystem that has been actively maintained throughout 2024-2025:
1. **October 2024** - Commit 088984c8d54c: Fixed critical bug where PRM handlers caused paging errors due to incorrect memory type usage (marked for stable, had Fixes tag)
2. **January 2025** - Commit 7f5704b6a143b: Fixed regression from above where overly strict NULL checks broke real hardware. According to PRM specification section 4.1.2, `static_data_buffer_address` and `acpi_param_buffer_address` can legitimately be NULL. This was a real bug reported by Shi Liu from Tencent (marked Cc: stable)
3. **July 2025** - Commit aae68a5f4844e/3db5648c4d608: Reduced unnecessary warning messages that confused users when legitimate NULL addresses were encountered per PRM spec
4. **August 2025** - Current commit 311942ce763e2: Adds handler skipping logic for NULL addresses
#### **What This Commit Actually Fixes**
The commit adds two defensive checks in `acpi_parse_prmt()` at drivers/acpi/prmt.c:133-186:
**First Check (lines 150+):** ```c if (unlikely(!handler_info->handler_address)) { pr_info("Skipping handler with NULL address for GUID: %pUL", ...); continue; } ``` Detects when ACPI firmware table provides a handler with NULL physical address - indicates buggy/malformed firmware.
**Second Check (lines 159+):** ```c if (unlikely(!th->handler_addr)) { pr_warn("Failed to find VA of handler for GUID: %pUL, PA: 0x%llx", ...); continue; // <-- NEW } ``` Adds `continue` statement when VA lookup fails (previously just printed warning and continued processing).
#### **Current vs. New Behavior**
**Before this fix:** - Handlers with NULL physical addresses or failed VA lookups are added to the `tm->handlers[]` array - They waste memory allocation - Warning messages are printed during initialization - Later runtime check at line 312 in `acpi_platformrt_space_handler()` catches attempts to use NULL handlers and returns error - Potentially confusing for users/debugging
**After this fix:** - Handlers with NULL addresses are still partially added (GUID is copied before the check), but VA lookup and buffer address initialization are skipped - Clearer, more specific error messages (pr_info for NULL PA, pr_warn for failed VA lookup) - Slightly more efficient initialization (skips unnecessary efi_pa_va_lookup calls) - Better fail-fast behavior during parsing vs. runtime
#### **Why This Should Be Backported**
**1. Robustness Improvement in Active Bugfix Area** The ACPI PRM subsystem has had multiple real-world bugs requiring stable backports (commits 088984c8d54c and 7f5704b6a143b both marked for stable). This continues the pattern of hardening this code against edge cases and firmware bugs.
**2. Handles Real-World Firmware Issues** While the code comment states NULL handler_addr "is not expected to ever happen," the fact that this check exists and multiple firmware-related fixes have been needed suggests buggy ACPI tables do exist in the field. The author (from Lenovo) likely encountered this on actual hardware.
**3. Improves Error Reporting** Users encountering this condition get clearer, more actionable messages: - "Skipping handler with NULL address" (pr_info) vs. just a warning - Distinguishes between NULL PA from firmware vs. failed VA lookup
**4. Low Regression Risk** - Changes are minimal (adds 2 checks with `continue` statements) - Only affects edge case error path (NULL handlers) - Existing runtime check at line 312 provides safety net - Code is well-commented and reviewed by subsystem maintainer Rafael Wysocki
**5. Prevents Wasted Resources** Skips unnecessary efi_pa_va_lookup() calls and buffer address setup for handlers that will never be usable.
**6. Follows Stable Backport Criteria** - ✓ Obviously correct and contained - ✓ Fixes handling of buggy firmware (real issue users may encounter) - ✓ Doesn't introduce new features - ✓ No architectural changes - ✓ Minimal risk - ✓ Confined to ACPI PRM subsystem
#### **Potential Concerns**
The implementation has a minor quirk: handlers are partially initialized (GUID copied before checks) before being skipped, leaving "holes" in the handlers array. However, this doesn't cause functional problems because: - The `find_guid_info()` function searches by GUID matching - Incomplete handlers won't match lookup requests (or will fail runtime check if somehow matched) - This is actually similar to existing behavior
#### **Evidence of Selection for Backporting**
The commit was authored Aug 25, 2025 and committed Sep 4, 2025 by Rafael Wysocki (ACPI subsystem maintainer), indicating it passed review and was deemed important enough for mainline. While there's no explicit "Cc: stable" tag, the pattern of recent PRM fixes being backported suggests this fits the stable criteria.
#### **Conclusion**
**YES - This commit should be backported to stable kernel trees.**
While not fixing a critical crash or security vulnerability, it improves robustness and error handling in a subsystem with documented real-world firmware issues. The change is small, safe, well-contained, and follows recent patterns of PRM hardening that have been successfully backported. The improvement in error detection and reporting provides value to users encountering buggy ACPI firmware implementations.
drivers/acpi/prmt.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index be033bbb126a4..6792d4385eee4 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -150,15 +150,28 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) th = &tm->handlers[cur_handler];
guid_copy(&th->guid, (guid_t *)handler_info->handler_guid); + + /* + * Print an error message if handler_address is NULL, the parse of VA also + * can be skipped. + */ + if (unlikely(!handler_info->handler_address)) { + pr_info("Skipping handler with NULL address for GUID: %pUL", + (guid_t *)handler_info->handler_guid); + continue; + } + th->handler_addr = (void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address); /* - * Print a warning message if handler_addr is zero which is not expected to - * ever happen. + * Print a warning message and skip the parse of VA if handler_addr is zero + * which is not expected to ever happen. */ - if (unlikely(!th->handler_addr)) + if (unlikely(!th->handler_addr)) { pr_warn("Failed to find VA of handler for GUID: %pUL, PA: 0x%llx", &th->guid, handler_info->handler_address); + continue; + }
th->static_data_buffer_addr = efi_pa_va_lookup(&th->guid, handler_info->static_data_buffer_address);