Commit 99280413 authored by Ard Biesheuvel's avatar Ard Biesheuvel

efi: Add missing __nocfi annotations to runtime wrappers

The EFI runtime wrappers are a sandbox for calling into EFI runtime
services, which are invoked using indirect calls. When running with kCFI
enabled, the compiler will require the target of any indirect call to be
type annotated.

Given that the EFI runtime services prototypes and calling convention
are governed by the EFI spec, not the Linux kernel, adding such type
annotations for firmware routines is infeasible, and so the compiler
must be informed that prototype validation should be omitted.

Add the __nocfi annotation at the appropriate places in the EFI runtime
wrapper code to achieve this.

Note that this currently only affects 32-bit ARM, given that other
architectures that support both kCFI and EFI use an asm wrapper to call
EFI runtime services, and this hides the indirect call from the
compiler.

Fixes: 1a4fec49 ("ARM: 9392/2: Support CLANG CFI")
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Tested-by: default avatarNathan Chancellor <nathan@kernel.org>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 290be0a4
...@@ -213,7 +213,7 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock); ...@@ -213,7 +213,7 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock);
* Calls the appropriate efi_runtime_service() with the appropriate * Calls the appropriate efi_runtime_service() with the appropriate
* arguments. * arguments.
*/ */
static void efi_call_rts(struct work_struct *work) static void __nocfi efi_call_rts(struct work_struct *work)
{ {
const union efi_rts_args *args = efi_rts_work.args; const union efi_rts_args *args = efi_rts_work.args;
efi_status_t status = EFI_NOT_FOUND; efi_status_t status = EFI_NOT_FOUND;
...@@ -435,7 +435,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, ...@@ -435,7 +435,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
return status; return status;
} }
static efi_status_t static efi_status_t __nocfi
virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr, virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr,
unsigned long data_size, void *data) unsigned long data_size, void *data)
{ {
...@@ -469,7 +469,7 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, ...@@ -469,7 +469,7 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
return status; return status;
} }
static efi_status_t static efi_status_t __nocfi
virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space, virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space,
u64 *remaining_space, u64 *max_variable_size) u64 *remaining_space, u64 *max_variable_size)
{ {
...@@ -499,10 +499,9 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) ...@@ -499,10 +499,9 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
return status; return status;
} }
static void virt_efi_reset_system(int reset_type, static void __nocfi
efi_status_t status, virt_efi_reset_system(int reset_type, efi_status_t status,
unsigned long data_size, unsigned long data_size, efi_char16_t *data)
efi_char16_t *data)
{ {
if (down_trylock(&efi_runtime_lock)) { if (down_trylock(&efi_runtime_lock)) {
pr_warn("failed to invoke the reset_system() runtime service:\n" pr_warn("failed to invoke the reset_system() runtime service:\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment