Skip to content

Commit 795fffe

Browse files
committed
acpi/prmt: Use EFI runtime sandbox to invoke PRM handlers
JIRA: https://issues.redhat.com/browse/RHEL-22695 Tested: sanity commit 5894cf5 Author: Ard Biesheuvel <[email protected]> Date: Sun Jul 2 11:57:34 2023 +0200 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 <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Aristeu Rozanski <[email protected]>
1 parent f4b603e commit 795fffe

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
@@ -589,7 +589,7 @@ config ACPI_VIOT
589589

590590
config ACPI_PRMT
591591
bool "Platform Runtime Mechanism Support"
592-
depends on EFI && (X86_64 || ARM64)
592+
depends on EFI_RUNTIME_WRAPPERS && (X86_64 || ARM64)
593593
default y
594594
help
595595
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
@@ -1274,6 +1274,10 @@ extern int efi_tpm_final_log_size;
12741274

12751275
extern unsigned long rci2_table_phys;
12761276

1277+
efi_status_t
1278+
efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *),
1279+
u64 param_buffer_addr, void *context);
1280+
12771281
/*
12781282
* efi_runtime_service() function identifiers.
12791283
* "NONE" is used by efi_recover_from_page_fault() to check if the page
@@ -1293,6 +1297,7 @@ enum efi_rts_ids {
12931297
EFI_RESET_SYSTEM,
12941298
EFI_UPDATE_CAPSULE,
12951299
EFI_QUERY_CAPSULE_CAPS,
1300+
EFI_ACPI_PRM_HANDLER,
12961301
};
12971302

12981303
union efi_rts_args;

0 commit comments

Comments
 (0)