Dan Carpenter (1): ACPI: PRM: Clean up guid type in struct prm_handler_info
Koba Ko (1): ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context
drivers/acpi/prmt.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/13303 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/D...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/13303 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/D...
From: Koba Ko kobak@nvidia.com
mainline inclusion from mainline-v6.12-rc5 commit 088984c8d54c0053fc4ae606981291d741c5924b category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB2SU5 CVE: CVE-2024-50141
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
-------------------------------------
PRMT needs to find the correct type of block to translate the PA-VA mapping for EFI runtime services.
The issue arises because the PRMT is finding a block of type EFI_CONVENTIONAL_MEMORY, which is not appropriate for runtime services as described in Section 2.2.2 (Runtime Services) of the UEFI Specification [1]. Since the PRM handler is a type of runtime service, this causes an exception when the PRM handler is called.
[Firmware Bug]: Unable to handle paging request in EFI runtime service WARNING: CPU: 22 PID: 4330 at drivers/firmware/efi/runtime-wrappers.c:341 __efi_queue_work+0x11c/0x170 Call trace:
Let PRMT find a block with EFI_MEMORY_RUNTIME for PRM handler and PRM context.
If no suitable block is found, a warning message will be printed, but the procedure continues to manage the next PRM handler.
However, if the PRM handler is actually called without proper allocation, it would result in a failure during error handling.
By using the correct memory types for runtime services, ensure that the PRM handler and the context are properly mapped in the virtual address space during runtime, preventing the paging request error.
The issue is really that only memory that has been remapped for runtime by the firmware can be used by the PRM handler, and so the region needs to have the EFI_MEMORY_RUNTIME attribute.
Link: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf # [1] Fixes: cefc7ca46235 ("ACPI: PRM: implement OperationRegion handler for the PlatformRtMechanism subtype") Cc: All applicable stable@vger.kernel.org Signed-off-by: Koba Ko kobak@nvidia.com Reviewed-by: Matthew R. Ochs mochs@nvidia.com Reviewed-by: Zhang Rui rui.zhang@intel.com Reviewed-by: Ard Biesheuvel ardb@kernel.org Link: https://patch.msgid.link/20241012205010.4165798-1-kobak@nvidia.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Xiangwei Li liwei728@huawei.com --- drivers/acpi/prmt.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 3d4c4620f9f9..44d2d9084e4b 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -72,17 +72,21 @@ struct prm_module_info { struct prm_handler_info handlers[]; };
-static u64 efi_pa_va_lookup(u64 pa) +static u64 efi_pa_va_lookup(efi_guid_t *guid, u64 pa) { efi_memory_desc_t *md; u64 pa_offset = pa & ~PAGE_MASK; u64 page = pa & PAGE_MASK;
for_each_efi_memory_desc(md) { - if (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages) + if ((md->attribute & EFI_MEMORY_RUNTIME) && + (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)) { return pa_offset + md->virt_addr + page - md->phys_addr; + } }
+ pr_warn("Failed to find VA for GUID: %pUL, PA: 0x%llx", guid, pa); + return 0; }
@@ -148,9 +152,15 @@ 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); - th->handler_addr = (void *)efi_pa_va_lookup(handler_info->handler_address); - th->static_data_buffer_addr = efi_pa_va_lookup(handler_info->static_data_buffer_address); - th->acpi_param_buffer_addr = efi_pa_va_lookup(handler_info->acpi_param_buffer_address); + th->handler_addr = + (void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address); + + th->static_data_buffer_addr = + efi_pa_va_lookup(&th->guid, handler_info->static_data_buffer_address); + + th->acpi_param_buffer_addr = + efi_pa_va_lookup(&th->guid, handler_info->acpi_param_buffer_address); + } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info)));
return 0; @@ -253,6 +263,13 @@ static acpi_status acpi_platformrt_space_handler(u32 function, if (!handler || !module) goto invalid_guid;
+ if (!handler->handler_addr || + !handler->static_data_buffer_addr || + !handler->acpi_param_buffer_addr) { + buffer->prm_status = PRM_HANDLER_ERROR; + return AE_OK; + } + ACPI_COPY_NAMESEG(context.signature, "PRMC"); context.revision = 0x0; context.reserved = 0x0;
From: Dan Carpenter dan.carpenter@linaro.org
mainline inclusion from mainline-v6.12-rc5 commit 3d1c651272cf1df8aac7d9b6d92d836d27bed50f category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB2SU5 CVE: CVE-2024-50141
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
-------------------------------------
Clang 19 prints a warning when we pass &th->guid to efi_pa_va_lookup():
drivers/acpi/prmt.c:156:29: error: passing 1-byte aligned argument to 4-byte aligned parameter 1 of 'efi_pa_va_lookup' may result in an unaligned pointer access [-Werror,-Walign-mismatch] 156 | (void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address); | ^
The problem is that efi_pa_va_lookup() takes a efi_guid_t and &th->guid is a regular guid_t. The difference between the two types is the alignment. efi_guid_t is a typedef.
typedef guid_t efi_guid_t __aligned(__alignof__(u32));
It's possible that this a bug in Clang 19. Even though the alignment of &th->guid is not explicitly specified, it will still end up being aligned at 4 or 8 bytes.
Anyway, as Ard points out, it's cleaner to change guid to efi_guid_t type and that also makes the warning go away.
Fixes: 088984c8d54c ("ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context") Reported-by: Linux Kernel Functional Testing lkft@linaro.org Suggested-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Tested-by: Paul E. McKenney paulmck@kernel.org Acked-by: Ard Biesheuvel ardb@kernel.org Link: https://patch.msgid.link/3777d71b-9e19-45f4-be4e-17bf4fa7a834@stanley.mounta... [ rjw: Subject edit ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com
Conflicts: drivers/acpi/prmt.ci [context conflict] Signed-off-by: Xiangwei Li liwei728@huawei.com --- drivers/acpi/prmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 44d2d9084e4b..dd0261fd12d6 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -52,7 +52,7 @@ struct prm_context_buffer { static LIST_HEAD(prm_module_list);
struct prm_handler_info { - guid_t guid; + efi_guid_t guid; void *handler_addr; u64 static_data_buffer_addr; u64 acpi_param_buffer_addr;