Re: [PATCH 4/4] acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers

Rafael J. Wysocki
2023-08-17T17:56:07Z

On Fri, Aug 4, 2023 at 6:04 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> Instead of bypassing the kernel's adaptation layer for performing EFI
> runtime calls, wire up ACPI PRM handling into it. This means these calls
> can no longer occur concurrently with EFI runtime calls, and will be
> made from the EFI runtime workqueue. It also means any page faults
> occurring during PRM handling will be identified correctly as
> originating in firmware code.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Thanks!

> ---
> drivers/acpi/prmt.c | 8 ++++----
> drivers/firmware/efi/runtime-wrappers.c | 20 ++++++++++++++++++++
> include/linux/efi.h | 13 +++++++++++++
> 3 files changed, 37 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c
> index 3d4c4620f9f95309..95be1c80db387faa 100644
> --- a/drivers/acpi/prmt.c
> +++ b/drivers/acpi/prmt.c
> @@ -53,7 +53,7 @@ static LIST_HEAD(prm_module_list);
>
> struct prm_handler_info {
> guid_t guid;
> - void *handler_addr;
> + efi_acpi_prm_handler_t *handler_addr;
> u64 static_data_buffer_addr;
> u64 acpi_param_buffer_addr;
>
> @@ -260,9 +260,9 @@ static acpi_status acpi_platformrt_space_handler(u32 function,
> context.static_data_buffer = handler->static_data_buffer_addr;
> context.mmio_ranges = module->mmio_info;
>
> - status = efi_call_virt_pointer(handler, handler_addr,
> - handler->acpi_param_buffer_addr,
> - &context);
> + status = efi_call_acpi_prm_handler(handler->handler_addr,
> + handler->acpi_param_buffer_addr,
> + &context);
> if (status == EFI_SUCCESS) {
> buffer->prm_status = PRM_HANDLER_SUCCESS;
> } else {
> diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
> index b3ef208299ae591e..ce306cd1efdfda21 100644
> --- a/drivers/firmware/efi/runtime-wrappers.c
> +++ b/drivers/firmware/efi/runtime-wrappers.c
> @@ -212,6 +212,12 @@ static void efi_call_rts(struct work_struct *work)
> efi_rts_work.QUERY_CAPSULE_CAPS.max_size,
> efi_rts_work.QUERY_CAPSULE_CAPS.reset_type);
> break;
> + case EFI_ACPI_PRM_HANDLER:
> + status = efi_call_virt_pointer(&efi_rts_work.ACPI_PRM_HANDLER,
> + handler_addr,
> + efi_rts_work.ACPI_PRM_HANDLER.param_buffer_addr,
> + efi_rts_work.ACPI_PRM_HANDLER.context);
> + break;
> default:
> /*
> * Ideally, we should never reach here because a caller of this
> @@ -475,3 +481,17 @@ void __init efi_native_runtime_setup(void)
> efi.update_capsule = virt_efi_update_capsule;
> efi.query_capsule_caps = virt_efi_query_capsule_caps;
> }
> +
> +efi_status_t efi_call_acpi_prm_handler(efi_acpi_prm_handler_t *handler_addr,
> + efi_physical_addr_t param_buffer_addr,
> + void *context)
> +{
> + efi_status_t status;
> +
> + if (down_interruptible(&efi_runtime_lock))
> + return EFI_ABORTED;
> + status = efi_queue_work(ACPI_PRM_HANDLER, handler_addr,
> + param_buffer_addr, context);
> + up(&efi_runtime_lock);
> + return status;
> +}
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index c72715821016851b..065af735d90a411c 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1230,6 +1230,12 @@ extern int efi_tpm_final_log_size;
>
> extern unsigned long rci2_table_phys;
>
> +typedef efi_status_t (__efiapi efi_acpi_prm_handler_t)(efi_physical_addr_t, void *);
> +
> +efi_status_t efi_call_acpi_prm_handler(efi_acpi_prm_handler_t *handler_addr,
> + efi_physical_addr_t param_buffer_addr,
> + void *context);
> +
> /*
> * efi_runtime_service() function identifiers.
> * "NONE" is used by efi_recover_from_page_fault() to check if the page
> @@ -1249,6 +1255,7 @@ enum efi_rts_ids {
> EFI_RESET_SYSTEM,
> EFI_UPDATE_CAPSULE,
> EFI_QUERY_CAPSULE_CAPS,
> + EFI_ACPI_PRM_HANDLER,
> };
>
> /*
> @@ -1324,6 +1331,12 @@ struct efi_runtime_work {
> u64 *max_size;
> int *reset_type;
> } QUERY_CAPSULE_CAPS;
> +
> + struct {
> + efi_acpi_prm_handler_t *handler_addr;
> + efi_physical_addr_t param_buffer_addr;
> + void *context;
> + } ACPI_PRM_HANDLER;
> };
> efi_status_t status;
> struct work_struct work;
> --
> 2.39.2
>