Path: blob/master/drivers/firmware/efi/runtime-wrappers.c
26428 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* runtime-wrappers.c - Runtime Services function call wrappers3*4* Implementation summary:5* -----------------------6* 1. When user/kernel thread requests to execute efi_runtime_service(),7* enqueue work to efi_rts_wq.8* 2. Caller thread waits for completion until the work is finished9* because it's dependent on the return status and execution of10* efi_runtime_service().11* For instance, get_variable() and get_next_variable().12*13* Copyright (C) 2014 Linaro Ltd. <[email protected]>14*15* Split off from arch/x86/platform/efi/efi.c16*17* Copyright (C) 1999 VA Linux Systems18* Copyright (C) 1999 Walt Drummond <[email protected]>19* Copyright (C) 1999-2002 Hewlett-Packard Co.20* Copyright (C) 2005-2008 Intel Co.21* Copyright (C) 2013 SuSE Labs22*/2324#define pr_fmt(fmt) "efi: " fmt2526#include <linux/bug.h>27#include <linux/efi.h>28#include <linux/irqflags.h>29#include <linux/mutex.h>30#include <linux/semaphore.h>31#include <linux/stringify.h>32#include <linux/workqueue.h>33#include <linux/completion.h>3435#include <asm/efi.h>3637/*38* Wrap around the new efi_call_virt_generic() macros so that the39* code doesn't get too cluttered:40*/41#define efi_call_virt(f, args...) \42arch_efi_call_virt(efi.runtime, f, args)4344union efi_rts_args {45struct {46efi_time_t *time;47efi_time_cap_t *capabilities;48} GET_TIME;4950struct {51efi_time_t *time;52} SET_TIME;5354struct {55efi_bool_t *enabled;56efi_bool_t *pending;57efi_time_t *time;58} GET_WAKEUP_TIME;5960struct {61efi_bool_t enable;62efi_time_t *time;63} SET_WAKEUP_TIME;6465struct {66efi_char16_t *name;67efi_guid_t *vendor;68u32 *attr;69unsigned long *data_size;70void *data;71} GET_VARIABLE;7273struct {74unsigned long *name_size;75efi_char16_t *name;76efi_guid_t *vendor;77} GET_NEXT_VARIABLE;7879struct {80efi_char16_t *name;81efi_guid_t *vendor;82u32 attr;83unsigned long data_size;84void *data;85} SET_VARIABLE;8687struct {88u32 attr;89u64 *storage_space;90u64 *remaining_space;91u64 *max_variable_size;92} QUERY_VARIABLE_INFO;9394struct {95u32 *high_count;96} GET_NEXT_HIGH_MONO_COUNT;9798struct {99efi_capsule_header_t **capsules;100unsigned long count;101unsigned long sg_list;102} UPDATE_CAPSULE;103104struct {105efi_capsule_header_t **capsules;106unsigned long count;107u64 *max_size;108int *reset_type;109} QUERY_CAPSULE_CAPS;110111struct {112efi_status_t (__efiapi *acpi_prm_handler)(u64, void *);113u64 param_buffer_addr;114void *context;115} ACPI_PRM_HANDLER;116};117118struct efi_runtime_work efi_rts_work;119120/*121* efi_queue_work: Queue EFI runtime service call and wait for completion122* @_rts: EFI runtime service function identifier123* @_args: Arguments to pass to the EFI runtime service124*125* Accesses to efi_runtime_services() are serialized by a binary126* semaphore (efi_runtime_lock) and caller waits until the work is127* finished, hence _only_ one work is queued at a time and the caller128* thread waits for completion.129*/130#define efi_queue_work(_rts, _args...) \131__efi_queue_work(EFI_ ## _rts, \132&(union efi_rts_args){ ._rts = { _args }})133134#ifndef arch_efi_save_flags135#define arch_efi_save_flags(state_flags) local_save_flags(state_flags)136#define arch_efi_restore_flags(state_flags) local_irq_restore(state_flags)137#endif138139unsigned long efi_call_virt_save_flags(void)140{141unsigned long flags;142143arch_efi_save_flags(flags);144return flags;145}146147void efi_call_virt_check_flags(unsigned long flags, const void *caller)148{149unsigned long cur_flags, mismatch;150151cur_flags = efi_call_virt_save_flags();152153mismatch = flags ^ cur_flags;154if (!WARN_ON_ONCE(mismatch & ARCH_EFI_IRQ_FLAGS_MASK))155return;156157add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_NOW_UNRELIABLE);158pr_err_ratelimited(FW_BUG "IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI call from %pS\n",159flags, cur_flags, caller ?: __builtin_return_address(0));160arch_efi_restore_flags(flags);161}162163/*164* According to section 7.1 of the UEFI spec, Runtime Services are not fully165* reentrant, and there are particular combinations of calls that need to be166* serialized. (source: UEFI Specification v2.4A)167*168* Table 31. Rules for Reentry Into Runtime Services169* +------------------------------------+-------------------------------+170* | If previous call is busy in | Forbidden to call |171* +------------------------------------+-------------------------------+172* | Any | SetVirtualAddressMap() |173* +------------------------------------+-------------------------------+174* | ConvertPointer() | ConvertPointer() |175* +------------------------------------+-------------------------------+176* | SetVariable() | ResetSystem() |177* | UpdateCapsule() | |178* | SetTime() | |179* | SetWakeupTime() | |180* | GetNextHighMonotonicCount() | |181* +------------------------------------+-------------------------------+182* | GetVariable() | GetVariable() |183* | GetNextVariableName() | GetNextVariableName() |184* | SetVariable() | SetVariable() |185* | QueryVariableInfo() | QueryVariableInfo() |186* | UpdateCapsule() | UpdateCapsule() |187* | QueryCapsuleCapabilities() | QueryCapsuleCapabilities() |188* | GetNextHighMonotonicCount() | GetNextHighMonotonicCount() |189* +------------------------------------+-------------------------------+190* | GetTime() | GetTime() |191* | SetTime() | SetTime() |192* | GetWakeupTime() | GetWakeupTime() |193* | SetWakeupTime() | SetWakeupTime() |194* +------------------------------------+-------------------------------+195*196* Due to the fact that the EFI pstore may write to the variable store in197* interrupt context, we need to use a lock for at least the groups that198* contain SetVariable() and QueryVariableInfo(). That leaves little else, as199* none of the remaining functions are actually ever called at runtime.200* So let's just use a single lock to serialize all Runtime Services calls.201*/202static DEFINE_SEMAPHORE(efi_runtime_lock, 1);203204/*205* Expose the EFI runtime lock to the UV platform206*/207#ifdef CONFIG_X86_UV208extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock);209#endif210211/*212* Calls the appropriate efi_runtime_service() with the appropriate213* arguments.214*/215static void __nocfi efi_call_rts(struct work_struct *work)216{217const union efi_rts_args *args = efi_rts_work.args;218efi_status_t status = EFI_NOT_FOUND;219unsigned long flags;220221arch_efi_call_virt_setup();222flags = efi_call_virt_save_flags();223224switch (efi_rts_work.efi_rts_id) {225case EFI_GET_TIME:226status = efi_call_virt(get_time,227args->GET_TIME.time,228args->GET_TIME.capabilities);229break;230case EFI_SET_TIME:231status = efi_call_virt(set_time,232args->SET_TIME.time);233break;234case EFI_GET_WAKEUP_TIME:235status = efi_call_virt(get_wakeup_time,236args->GET_WAKEUP_TIME.enabled,237args->GET_WAKEUP_TIME.pending,238args->GET_WAKEUP_TIME.time);239break;240case EFI_SET_WAKEUP_TIME:241status = efi_call_virt(set_wakeup_time,242args->SET_WAKEUP_TIME.enable,243args->SET_WAKEUP_TIME.time);244break;245case EFI_GET_VARIABLE:246status = efi_call_virt(get_variable,247args->GET_VARIABLE.name,248args->GET_VARIABLE.vendor,249args->GET_VARIABLE.attr,250args->GET_VARIABLE.data_size,251args->GET_VARIABLE.data);252break;253case EFI_GET_NEXT_VARIABLE:254status = efi_call_virt(get_next_variable,255args->GET_NEXT_VARIABLE.name_size,256args->GET_NEXT_VARIABLE.name,257args->GET_NEXT_VARIABLE.vendor);258break;259case EFI_SET_VARIABLE:260status = efi_call_virt(set_variable,261args->SET_VARIABLE.name,262args->SET_VARIABLE.vendor,263args->SET_VARIABLE.attr,264args->SET_VARIABLE.data_size,265args->SET_VARIABLE.data);266break;267case EFI_QUERY_VARIABLE_INFO:268status = efi_call_virt(query_variable_info,269args->QUERY_VARIABLE_INFO.attr,270args->QUERY_VARIABLE_INFO.storage_space,271args->QUERY_VARIABLE_INFO.remaining_space,272args->QUERY_VARIABLE_INFO.max_variable_size);273break;274case EFI_GET_NEXT_HIGH_MONO_COUNT:275status = efi_call_virt(get_next_high_mono_count,276args->GET_NEXT_HIGH_MONO_COUNT.high_count);277break;278case EFI_UPDATE_CAPSULE:279status = efi_call_virt(update_capsule,280args->UPDATE_CAPSULE.capsules,281args->UPDATE_CAPSULE.count,282args->UPDATE_CAPSULE.sg_list);283break;284case EFI_QUERY_CAPSULE_CAPS:285status = efi_call_virt(query_capsule_caps,286args->QUERY_CAPSULE_CAPS.capsules,287args->QUERY_CAPSULE_CAPS.count,288args->QUERY_CAPSULE_CAPS.max_size,289args->QUERY_CAPSULE_CAPS.reset_type);290break;291case EFI_ACPI_PRM_HANDLER:292#ifdef CONFIG_ACPI_PRMT293status = arch_efi_call_virt(args, ACPI_PRM_HANDLER.acpi_prm_handler,294args->ACPI_PRM_HANDLER.param_buffer_addr,295args->ACPI_PRM_HANDLER.context);296break;297#endif298default:299/*300* Ideally, we should never reach here because a caller of this301* function should have put the right efi_runtime_service()302* function identifier into efi_rts_work->efi_rts_id303*/304pr_err("Requested executing invalid EFI Runtime Service.\n");305}306307efi_call_virt_check_flags(flags, efi_rts_work.caller);308arch_efi_call_virt_teardown();309310efi_rts_work.status = status;311complete(&efi_rts_work.efi_rts_comp);312}313314static efi_status_t __efi_queue_work(enum efi_rts_ids id,315union efi_rts_args *args)316{317efi_rts_work.efi_rts_id = id;318efi_rts_work.args = args;319efi_rts_work.caller = __builtin_return_address(0);320efi_rts_work.status = EFI_ABORTED;321322if (!efi_enabled(EFI_RUNTIME_SERVICES)) {323pr_warn_once("EFI Runtime Services are disabled!\n");324efi_rts_work.status = EFI_DEVICE_ERROR;325goto exit;326}327328init_completion(&efi_rts_work.efi_rts_comp);329INIT_WORK(&efi_rts_work.work, efi_call_rts);330331/*332* queue_work() returns 0 if work was already on queue,333* _ideally_ this should never happen.334*/335if (queue_work(efi_rts_wq, &efi_rts_work.work))336wait_for_completion(&efi_rts_work.efi_rts_comp);337else338pr_err("Failed to queue work to efi_rts_wq.\n");339340WARN_ON_ONCE(efi_rts_work.status == EFI_ABORTED);341exit:342efi_rts_work.efi_rts_id = EFI_NONE;343return efi_rts_work.status;344}345346static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)347{348efi_status_t status;349350if (down_interruptible(&efi_runtime_lock))351return EFI_ABORTED;352status = efi_queue_work(GET_TIME, tm, tc);353up(&efi_runtime_lock);354return status;355}356357static efi_status_t virt_efi_set_time(efi_time_t *tm)358{359efi_status_t status;360361if (down_interruptible(&efi_runtime_lock))362return EFI_ABORTED;363status = efi_queue_work(SET_TIME, tm);364up(&efi_runtime_lock);365return status;366}367368static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,369efi_bool_t *pending,370efi_time_t *tm)371{372efi_status_t status;373374if (down_interruptible(&efi_runtime_lock))375return EFI_ABORTED;376status = efi_queue_work(GET_WAKEUP_TIME, enabled, pending, tm);377up(&efi_runtime_lock);378return status;379}380381static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)382{383efi_status_t status;384385if (down_interruptible(&efi_runtime_lock))386return EFI_ABORTED;387status = efi_queue_work(SET_WAKEUP_TIME, enabled, tm);388up(&efi_runtime_lock);389return status;390}391392static efi_status_t virt_efi_get_variable(efi_char16_t *name,393efi_guid_t *vendor,394u32 *attr,395unsigned long *data_size,396void *data)397{398efi_status_t status;399400if (down_interruptible(&efi_runtime_lock))401return EFI_ABORTED;402status = efi_queue_work(GET_VARIABLE, name, vendor, attr, data_size,403data);404up(&efi_runtime_lock);405return status;406}407408static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,409efi_char16_t *name,410efi_guid_t *vendor)411{412efi_status_t status;413414if (down_interruptible(&efi_runtime_lock))415return EFI_ABORTED;416status = efi_queue_work(GET_NEXT_VARIABLE, name_size, name, vendor);417up(&efi_runtime_lock);418return status;419}420421static efi_status_t virt_efi_set_variable(efi_char16_t *name,422efi_guid_t *vendor,423u32 attr,424unsigned long data_size,425void *data)426{427efi_status_t status;428429if (down_interruptible(&efi_runtime_lock))430return EFI_ABORTED;431status = efi_queue_work(SET_VARIABLE, name, vendor, attr, data_size,432data);433up(&efi_runtime_lock);434return status;435}436437static efi_status_t __nocfi438virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr,439unsigned long data_size, void *data)440{441efi_status_t status;442443if (down_trylock(&efi_runtime_lock))444return EFI_NOT_READY;445446status = efi_call_virt_pointer(efi.runtime, set_variable, name, vendor,447attr, data_size, data);448up(&efi_runtime_lock);449return status;450}451452453static efi_status_t virt_efi_query_variable_info(u32 attr,454u64 *storage_space,455u64 *remaining_space,456u64 *max_variable_size)457{458efi_status_t status;459460if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)461return EFI_UNSUPPORTED;462463if (down_interruptible(&efi_runtime_lock))464return EFI_ABORTED;465status = efi_queue_work(QUERY_VARIABLE_INFO, attr, storage_space,466remaining_space, max_variable_size);467up(&efi_runtime_lock);468return status;469}470471static efi_status_t __nocfi472virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space,473u64 *remaining_space, u64 *max_variable_size)474{475efi_status_t status;476477if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)478return EFI_UNSUPPORTED;479480if (down_trylock(&efi_runtime_lock))481return EFI_NOT_READY;482483status = efi_call_virt_pointer(efi.runtime, query_variable_info, attr,484storage_space, remaining_space,485max_variable_size);486up(&efi_runtime_lock);487return status;488}489490static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)491{492efi_status_t status;493494if (down_interruptible(&efi_runtime_lock))495return EFI_ABORTED;496status = efi_queue_work(GET_NEXT_HIGH_MONO_COUNT, count);497up(&efi_runtime_lock);498return status;499}500501static void __nocfi502virt_efi_reset_system(int reset_type, efi_status_t status,503unsigned long data_size, efi_char16_t *data)504{505if (down_trylock(&efi_runtime_lock)) {506pr_warn("failed to invoke the reset_system() runtime service:\n"507"could not get exclusive access to the firmware\n");508return;509}510511arch_efi_call_virt_setup();512efi_rts_work.efi_rts_id = EFI_RESET_SYSTEM;513arch_efi_call_virt(efi.runtime, reset_system, reset_type, status,514data_size, data);515arch_efi_call_virt_teardown();516517up(&efi_runtime_lock);518}519520static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,521unsigned long count,522unsigned long sg_list)523{524efi_status_t status;525526if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)527return EFI_UNSUPPORTED;528529if (down_interruptible(&efi_runtime_lock))530return EFI_ABORTED;531status = efi_queue_work(UPDATE_CAPSULE, capsules, count, sg_list);532up(&efi_runtime_lock);533return status;534}535536static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,537unsigned long count,538u64 *max_size,539int *reset_type)540{541efi_status_t status;542543if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)544return EFI_UNSUPPORTED;545546if (down_interruptible(&efi_runtime_lock))547return EFI_ABORTED;548status = efi_queue_work(QUERY_CAPSULE_CAPS, capsules, count,549max_size, reset_type);550up(&efi_runtime_lock);551return status;552}553554void __init efi_native_runtime_setup(void)555{556efi.get_time = virt_efi_get_time;557efi.set_time = virt_efi_set_time;558efi.get_wakeup_time = virt_efi_get_wakeup_time;559efi.set_wakeup_time = virt_efi_set_wakeup_time;560efi.get_variable = virt_efi_get_variable;561efi.get_next_variable = virt_efi_get_next_variable;562efi.set_variable = virt_efi_set_variable;563efi.set_variable_nonblocking = virt_efi_set_variable_nb;564efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;565efi.reset_system = virt_efi_reset_system;566efi.query_variable_info = virt_efi_query_variable_info;567efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nb;568efi.update_capsule = virt_efi_update_capsule;569efi.query_capsule_caps = virt_efi_query_capsule_caps;570}571572#ifdef CONFIG_ACPI_PRMT573574efi_status_t575efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *),576u64 param_buffer_addr, void *context)577{578efi_status_t status;579580if (down_interruptible(&efi_runtime_lock))581return EFI_ABORTED;582status = efi_queue_work(ACPI_PRM_HANDLER, handler_addr,583param_buffer_addr, context);584up(&efi_runtime_lock);585return status;586}587588#endif589590591