From: Ard Biesheuvel <ardb@kernel.org>
To: linux-efi@vger.kernel.org
Cc: linux-acpi@vger.kernel.org, rafael@kernel.org, lenb@kernel.org,
Ard Biesheuvel <ardb@kernel.org>
Subject: [PATCH 4/4] acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers
Date: Fri, 4 Aug 2023 18:03:59 +0200 [thread overview]
Message-ID: <20230804160359.228901-5-ardb@kernel.org> (raw)
In-Reply-To: <20230804160359.228901-1-ardb@kernel.org>
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>
---
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
next prev parent reply other threads:[~2023-08-04 16:04 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-04 16:03 [PATCH 0/4] efi: Clean up runtime wrapper and wire it up for PRM Ard Biesheuvel
2023-08-04 16:03 ` [PATCH 1/4] efi/runtime-wrappers: Use type safe encapsulation of call arguments Ard Biesheuvel
2023-08-04 16:03 ` [PATCH 2/4] efi/runtime-wrapper: Move workqueue manipulation out of line Ard Biesheuvel
2023-08-04 16:03 ` [PATCH 3/4] efi/runtime-wrappers: Remove duplicated macro for service returning void Ard Biesheuvel
2023-08-04 16:03 ` Ard Biesheuvel [this message]
2023-08-17 17:55 ` [PATCH 4/4] acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230804160359.228901-5-ardb@kernel.org \
--to=ardb@kernel.org \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=rafael@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox