|
@@ -45,39 +45,7 @@
|
|
|
#define __efi_call_virt(f, args...) \
|
|
|
__efi_call_virt_pointer(efi.systab->runtime, f, args)
|
|
|
|
|
|
-/* efi_runtime_service() function identifiers */
|
|
|
-enum efi_rts_ids {
|
|
|
- GET_TIME,
|
|
|
- SET_TIME,
|
|
|
- GET_WAKEUP_TIME,
|
|
|
- SET_WAKEUP_TIME,
|
|
|
- GET_VARIABLE,
|
|
|
- GET_NEXT_VARIABLE,
|
|
|
- SET_VARIABLE,
|
|
|
- QUERY_VARIABLE_INFO,
|
|
|
- GET_NEXT_HIGH_MONO_COUNT,
|
|
|
- UPDATE_CAPSULE,
|
|
|
- QUERY_CAPSULE_CAPS,
|
|
|
-};
|
|
|
-
|
|
|
-/*
|
|
|
- * efi_runtime_work: Details of EFI Runtime Service work
|
|
|
- * @arg<1-5>: EFI Runtime Service function arguments
|
|
|
- * @status: Status of executing EFI Runtime Service
|
|
|
- * @efi_rts_id: EFI Runtime Service function identifier
|
|
|
- * @efi_rts_comp: Struct used for handling completions
|
|
|
- */
|
|
|
-struct efi_runtime_work {
|
|
|
- void *arg1;
|
|
|
- void *arg2;
|
|
|
- void *arg3;
|
|
|
- void *arg4;
|
|
|
- void *arg5;
|
|
|
- efi_status_t status;
|
|
|
- struct work_struct work;
|
|
|
- enum efi_rts_ids efi_rts_id;
|
|
|
- struct completion efi_rts_comp;
|
|
|
-};
|
|
|
+struct efi_runtime_work efi_rts_work;
|
|
|
|
|
|
/*
|
|
|
* efi_queue_work: Queue efi_runtime_service() and wait until it's done
|
|
@@ -91,9 +59,13 @@ struct efi_runtime_work {
|
|
|
*/
|
|
|
#define efi_queue_work(_rts, _arg1, _arg2, _arg3, _arg4, _arg5) \
|
|
|
({ \
|
|
|
- struct efi_runtime_work efi_rts_work; \
|
|
|
efi_rts_work.status = EFI_ABORTED; \
|
|
|
\
|
|
|
+ if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \
|
|
|
+ pr_warn_once("EFI Runtime Services are disabled!\n"); \
|
|
|
+ goto exit; \
|
|
|
+ } \
|
|
|
+ \
|
|
|
init_completion(&efi_rts_work.efi_rts_comp); \
|
|
|
INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts); \
|
|
|
efi_rts_work.arg1 = _arg1; \
|
|
@@ -112,6 +84,8 @@ struct efi_runtime_work {
|
|
|
else \
|
|
|
pr_err("Failed to queue work to efi_rts_wq.\n"); \
|
|
|
\
|
|
|
+exit: \
|
|
|
+ efi_rts_work.efi_rts_id = NONE; \
|
|
|
efi_rts_work.status; \
|
|
|
})
|
|
|
|
|
@@ -184,18 +158,16 @@ static DEFINE_SEMAPHORE(efi_runtime_lock);
|
|
|
*/
|
|
|
static void efi_call_rts(struct work_struct *work)
|
|
|
{
|
|
|
- struct efi_runtime_work *efi_rts_work;
|
|
|
void *arg1, *arg2, *arg3, *arg4, *arg5;
|
|
|
efi_status_t status = EFI_NOT_FOUND;
|
|
|
|
|
|
- efi_rts_work = container_of(work, struct efi_runtime_work, work);
|
|
|
- arg1 = efi_rts_work->arg1;
|
|
|
- arg2 = efi_rts_work->arg2;
|
|
|
- arg3 = efi_rts_work->arg3;
|
|
|
- arg4 = efi_rts_work->arg4;
|
|
|
- arg5 = efi_rts_work->arg5;
|
|
|
+ arg1 = efi_rts_work.arg1;
|
|
|
+ arg2 = efi_rts_work.arg2;
|
|
|
+ arg3 = efi_rts_work.arg3;
|
|
|
+ arg4 = efi_rts_work.arg4;
|
|
|
+ arg5 = efi_rts_work.arg5;
|
|
|
|
|
|
- switch (efi_rts_work->efi_rts_id) {
|
|
|
+ switch (efi_rts_work.efi_rts_id) {
|
|
|
case GET_TIME:
|
|
|
status = efi_call_virt(get_time, (efi_time_t *)arg1,
|
|
|
(efi_time_cap_t *)arg2);
|
|
@@ -253,8 +225,8 @@ static void efi_call_rts(struct work_struct *work)
|
|
|
*/
|
|
|
pr_err("Requested executing invalid EFI Runtime Service.\n");
|
|
|
}
|
|
|
- efi_rts_work->status = status;
|
|
|
- complete(&efi_rts_work->efi_rts_comp);
|
|
|
+ efi_rts_work.status = status;
|
|
|
+ complete(&efi_rts_work.efi_rts_comp);
|
|
|
}
|
|
|
|
|
|
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
|
|
@@ -428,6 +400,7 @@ static void virt_efi_reset_system(int reset_type,
|
|
|
"could not get exclusive access to the firmware\n");
|
|
|
return;
|
|
|
}
|
|
|
+ efi_rts_work.efi_rts_id = RESET_SYSTEM;
|
|
|
__efi_call_virt(reset_system, reset_type, status, data_size, data);
|
|
|
up(&efi_runtime_lock);
|
|
|
}
|