Patch "ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     acpi-prm-find-efi_memory_runtime-block-for-prm-handl.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4829c847ef829ebcf36bebb1e4ca4fb8f03aaf06
Author: Koba Ko <kobak@xxxxxxxxxx>
Date:   Sun Oct 13 04:50:10 2024 +0800

    ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context
    
    [ Upstream commit 088984c8d54c0053fc4ae606981291d741c5924b ]
    
    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@xxxxxxxxxxxxxxx>
    Signed-off-by: Koba Ko <kobak@xxxxxxxxxx>
    Reviewed-by: Matthew R. Ochs <mochs@xxxxxxxxxx>
    Reviewed-by: Zhang Rui <rui.zhang@xxxxxxxxx>
    Reviewed-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
    Link: https://patch.msgid.link/20241012205010.4165798-1-kobak@xxxxxxxxxx
    [ rjw: Subject and changelog edits ]
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c
index 6da424f1f133f..63ead3f1d2947 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;
 }
 
@@ -136,9 +140,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;
@@ -232,6 +242,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;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux