Skip to content

Commit 5894cf5

Browse files
committed
acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers
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. Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 3c17ae4 commit 5894cf5

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

drivers/acpi/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ config ACPI_VIOT
581581

582582
config ACPI_PRMT
583583
bool "Platform Runtime Mechanism Support"
584-
depends on EFI && (X86_64 || ARM64)
584+
depends on EFI_RUNTIME_WRAPPERS && (X86_64 || ARM64)
585585
default y
586586
help
587587
Platform Runtime Mechanism (PRM) is a firmware interface exposing a

drivers/acpi/prmt.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,9 @@ static acpi_status acpi_platformrt_space_handler(u32 function,
260260
context.static_data_buffer = handler->static_data_buffer_addr;
261261
context.mmio_ranges = module->mmio_info;
262262

263-
status = efi_call_virt_pointer(handler, handler_addr,
264-
handler->acpi_param_buffer_addr,
265-
&context);
263+
status = efi_call_acpi_prm_handler(handler->handler_addr,
264+
handler->acpi_param_buffer_addr,
265+
&context);
266266
if (status == EFI_SUCCESS) {
267267
buffer->prm_status = PRM_HANDLER_SUCCESS;
268268
} else {

drivers/firmware/efi/runtime-wrappers.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ union efi_rts_args {
108108
u64 *max_size;
109109
int *reset_type;
110110
} QUERY_CAPSULE_CAPS;
111+
112+
struct {
113+
efi_status_t (__efiapi *acpi_prm_handler)(u64, void *);
114+
u64 param_buffer_addr;
115+
void *context;
116+
} ACPI_PRM_HANDLER;
111117
};
112118

113119
struct efi_runtime_work efi_rts_work;
@@ -283,6 +289,13 @@ static void efi_call_rts(struct work_struct *work)
283289
args->QUERY_CAPSULE_CAPS.max_size,
284290
args->QUERY_CAPSULE_CAPS.reset_type);
285291
break;
292+
case EFI_ACPI_PRM_HANDLER:
293+
#ifdef CONFIG_ACPI_PRMT
294+
status = arch_efi_call_virt(args, ACPI_PRM_HANDLER.acpi_prm_handler,
295+
args->ACPI_PRM_HANDLER.param_buffer_addr,
296+
args->ACPI_PRM_HANDLER.context);
297+
break;
298+
#endif
286299
default:
287300
/*
288301
* Ideally, we should never reach here because a caller of this
@@ -560,3 +573,21 @@ void efi_native_runtime_setup(void)
560573
efi.update_capsule = virt_efi_update_capsule;
561574
efi.query_capsule_caps = virt_efi_query_capsule_caps;
562575
}
576+
577+
#ifdef CONFIG_ACPI_PRMT
578+
579+
efi_status_t
580+
efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *),
581+
u64 param_buffer_addr, void *context)
582+
{
583+
efi_status_t status;
584+
585+
if (down_interruptible(&efi_runtime_lock))
586+
return EFI_ABORTED;
587+
status = efi_queue_work(ACPI_PRM_HANDLER, handler_addr,
588+
param_buffer_addr, context);
589+
up(&efi_runtime_lock);
590+
return status;
591+
}
592+
593+
#endif

include/linux/efi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,10 @@ extern int efi_tpm_final_log_size;
12281228

12291229
extern unsigned long rci2_table_phys;
12301230

1231+
efi_status_t
1232+
efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *),
1233+
u64 param_buffer_addr, void *context);
1234+
12311235
/*
12321236
* efi_runtime_service() function identifiers.
12331237
* "NONE" is used by efi_recover_from_page_fault() to check if the page
@@ -1247,6 +1251,7 @@ enum efi_rts_ids {
12471251
EFI_RESET_SYSTEM,
12481252
EFI_UPDATE_CAPSULE,
12491253
EFI_QUERY_CAPSULE_CAPS,
1254+
EFI_ACPI_PRM_HANDLER,
12501255
};
12511256

12521257
union efi_rts_args;

0 commit comments

Comments
 (0)