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

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

 



On Fri, Aug 4, 2023 at 6:04 PM Ard Biesheuvel <ardb@xxxxxxxxxx> 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@xxxxxxxxxx>

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

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
>



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux