4444#define __efi_call_virt (f , args ...) \
4545 __efi_call_virt_pointer(efi.runtime, f, args)
4646
47+ union efi_rts_args {
48+ struct {
49+ efi_time_t * time ;
50+ efi_time_cap_t * capabilities ;
51+ } GET_TIME ;
52+
53+ struct {
54+ efi_time_t * time ;
55+ } SET_TIME ;
56+
57+ struct {
58+ efi_bool_t * enabled ;
59+ efi_bool_t * pending ;
60+ efi_time_t * time ;
61+ } GET_WAKEUP_TIME ;
62+
63+ struct {
64+ efi_bool_t enable ;
65+ efi_time_t * time ;
66+ } SET_WAKEUP_TIME ;
67+
68+ struct {
69+ efi_char16_t * name ;
70+ efi_guid_t * vendor ;
71+ u32 * attr ;
72+ unsigned long * data_size ;
73+ void * data ;
74+ } GET_VARIABLE ;
75+
76+ struct {
77+ unsigned long * name_size ;
78+ efi_char16_t * name ;
79+ efi_guid_t * vendor ;
80+ } GET_NEXT_VARIABLE ;
81+
82+ struct {
83+ efi_char16_t * name ;
84+ efi_guid_t * vendor ;
85+ u32 attr ;
86+ unsigned long data_size ;
87+ void * data ;
88+ } SET_VARIABLE ;
89+
90+ struct {
91+ u32 attr ;
92+ u64 * storage_space ;
93+ u64 * remaining_space ;
94+ u64 * max_variable_size ;
95+ } QUERY_VARIABLE_INFO ;
96+
97+ struct {
98+ u32 * high_count ;
99+ } GET_NEXT_HIGH_MONO_COUNT ;
100+
101+ struct {
102+ efi_capsule_header_t * * capsules ;
103+ unsigned long count ;
104+ unsigned long sg_list ;
105+ } UPDATE_CAPSULE ;
106+
107+ struct {
108+ efi_capsule_header_t * * capsules ;
109+ unsigned long count ;
110+ u64 * max_size ;
111+ int * reset_type ;
112+ } QUERY_CAPSULE_CAPS ;
113+ };
114+
47115struct efi_runtime_work efi_rts_work ;
48116
49117/*
50- * efi_queue_work: Queue efi_runtime_service() and wait until it's done
51- * @rts : efi_runtime_service() function identifier
52- * @rts_arg<1-5>: efi_runtime_service() function arguments
118+ * efi_queue_work: Queue EFI runtime service call and wait for completion
119+ * @_rts : EFI runtime service function identifier
120+ * @_args: Arguments to pass to the EFI runtime service
53121 *
54122 * Accesses to efi_runtime_services() are serialized by a binary
55123 * semaphore (efi_runtime_lock) and caller waits until the work is
56124 * finished, hence _only_ one work is queued at a time and the caller
57125 * thread waits for completion.
58126 */
59- #define efi_queue_work (_rts , _arg1 , _arg2 , _arg3 , _arg4 , _arg5 ) \
127+ #define efi_queue_work (_rts , _args ...) \
60128({ \
129+ efi_rts_work.efi_rts_id = EFI_ ## _rts; \
130+ efi_rts_work.args = &(union efi_rts_args){ ._rts = { _args }}; \
61131 efi_rts_work.status = EFI_ABORTED; \
62132 \
63133 if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \
@@ -68,12 +138,6 @@ struct efi_runtime_work efi_rts_work;
68138 \
69139 init_completion(&efi_rts_work.efi_rts_comp); \
70140 INIT_WORK(&efi_rts_work.work, efi_call_rts); \
71- efi_rts_work.arg1 = _arg1; \
72- efi_rts_work.arg2 = _arg2; \
73- efi_rts_work.arg3 = _arg3; \
74- efi_rts_work.arg4 = _arg4; \
75- efi_rts_work.arg5 = _arg5; \
76- efi_rts_work.efi_rts_id = _rts; \
77141 \
78142 /* \
79143 * queue_work() returns 0 if work was already on queue, \
@@ -170,73 +234,78 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock);
170234/*
171235 * Calls the appropriate efi_runtime_service() with the appropriate
172236 * arguments.
173- *
174- * Semantics followed by efi_call_rts() to understand efi_runtime_work:
175- * 1. If argument was a pointer, recast it from void pointer to original
176- * pointer type.
177- * 2. If argument was a value, recast it from void pointer to original
178- * pointer type and dereference it.
179237 */
180238static void efi_call_rts (struct work_struct * work )
181239{
182- void * arg1 , * arg2 , * arg3 , * arg4 , * arg5 ;
240+ const union efi_rts_args * args = efi_rts_work . args ;
183241 efi_status_t status = EFI_NOT_FOUND ;
184242
185- arg1 = efi_rts_work .arg1 ;
186- arg2 = efi_rts_work .arg2 ;
187- arg3 = efi_rts_work .arg3 ;
188- arg4 = efi_rts_work .arg4 ;
189- arg5 = efi_rts_work .arg5 ;
190-
191243 switch (efi_rts_work .efi_rts_id ) {
192244 case EFI_GET_TIME :
193- status = efi_call_virt (get_time , (efi_time_t * )arg1 ,
194- (efi_time_cap_t * )arg2 );
245+ status = efi_call_virt (get_time ,
246+ args -> GET_TIME .time ,
247+ args -> GET_TIME .capabilities );
195248 break ;
196249 case EFI_SET_TIME :
197- status = efi_call_virt (set_time , (efi_time_t * )arg1 );
250+ status = efi_call_virt (set_time ,
251+ args -> SET_TIME .time );
198252 break ;
199253 case EFI_GET_WAKEUP_TIME :
200- status = efi_call_virt (get_wakeup_time , (efi_bool_t * )arg1 ,
201- (efi_bool_t * )arg2 , (efi_time_t * )arg3 );
254+ status = efi_call_virt (get_wakeup_time ,
255+ args -> GET_WAKEUP_TIME .enabled ,
256+ args -> GET_WAKEUP_TIME .pending ,
257+ args -> GET_WAKEUP_TIME .time );
202258 break ;
203259 case EFI_SET_WAKEUP_TIME :
204- status = efi_call_virt (set_wakeup_time , * (efi_bool_t * )arg1 ,
205- (efi_time_t * )arg2 );
260+ status = efi_call_virt (set_wakeup_time ,
261+ args -> SET_WAKEUP_TIME .enable ,
262+ args -> SET_WAKEUP_TIME .time );
206263 break ;
207264 case EFI_GET_VARIABLE :
208- status = efi_call_virt (get_variable , (efi_char16_t * )arg1 ,
209- (efi_guid_t * )arg2 , (u32 * )arg3 ,
210- (unsigned long * )arg4 , (void * )arg5 );
265+ status = efi_call_virt (get_variable ,
266+ args -> GET_VARIABLE .name ,
267+ args -> GET_VARIABLE .vendor ,
268+ args -> GET_VARIABLE .attr ,
269+ args -> GET_VARIABLE .data_size ,
270+ args -> GET_VARIABLE .data );
211271 break ;
212272 case EFI_GET_NEXT_VARIABLE :
213- status = efi_call_virt (get_next_variable , (unsigned long * )arg1 ,
214- (efi_char16_t * )arg2 ,
215- (efi_guid_t * )arg3 );
273+ status = efi_call_virt (get_next_variable ,
274+ args -> GET_NEXT_VARIABLE .name_size ,
275+ args -> GET_NEXT_VARIABLE .name ,
276+ args -> GET_NEXT_VARIABLE .vendor );
216277 break ;
217278 case EFI_SET_VARIABLE :
218- status = efi_call_virt (set_variable , (efi_char16_t * )arg1 ,
219- (efi_guid_t * )arg2 , * (u32 * )arg3 ,
220- * (unsigned long * )arg4 , (void * )arg5 );
279+ status = efi_call_virt (set_variable ,
280+ args -> SET_VARIABLE .name ,
281+ args -> SET_VARIABLE .vendor ,
282+ args -> SET_VARIABLE .attr ,
283+ args -> SET_VARIABLE .data_size ,
284+ args -> SET_VARIABLE .data );
221285 break ;
222286 case EFI_QUERY_VARIABLE_INFO :
223- status = efi_call_virt (query_variable_info , * (u32 * )arg1 ,
224- (u64 * )arg2 , (u64 * )arg3 , (u64 * )arg4 );
287+ status = efi_call_virt (query_variable_info ,
288+ args -> QUERY_VARIABLE_INFO .attr ,
289+ args -> QUERY_VARIABLE_INFO .storage_space ,
290+ args -> QUERY_VARIABLE_INFO .remaining_space ,
291+ args -> QUERY_VARIABLE_INFO .max_variable_size );
225292 break ;
226293 case EFI_GET_NEXT_HIGH_MONO_COUNT :
227- status = efi_call_virt (get_next_high_mono_count , (u32 * )arg1 );
294+ status = efi_call_virt (get_next_high_mono_count ,
295+ args -> GET_NEXT_HIGH_MONO_COUNT .high_count );
228296 break ;
229297 case EFI_UPDATE_CAPSULE :
230298 status = efi_call_virt (update_capsule ,
231- ( efi_capsule_header_t * * ) arg1 ,
232- * ( unsigned long * ) arg2 ,
233- * ( unsigned long * ) arg3 );
299+ args -> UPDATE_CAPSULE . capsules ,
300+ args -> UPDATE_CAPSULE . count ,
301+ args -> UPDATE_CAPSULE . sg_list );
234302 break ;
235303 case EFI_QUERY_CAPSULE_CAPS :
236304 status = efi_call_virt (query_capsule_caps ,
237- (efi_capsule_header_t * * )arg1 ,
238- * (unsigned long * )arg2 , (u64 * )arg3 ,
239- (int * )arg4 );
305+ args -> QUERY_CAPSULE_CAPS .capsules ,
306+ args -> QUERY_CAPSULE_CAPS .count ,
307+ args -> QUERY_CAPSULE_CAPS .max_size ,
308+ args -> QUERY_CAPSULE_CAPS .reset_type );
240309 break ;
241310 default :
242311 /*
@@ -256,7 +325,7 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
256325
257326 if (down_interruptible (& efi_runtime_lock ))
258327 return EFI_ABORTED ;
259- status = efi_queue_work (EFI_GET_TIME , tm , tc , NULL , NULL , NULL );
328+ status = efi_queue_work (GET_TIME , tm , tc );
260329 up (& efi_runtime_lock );
261330 return status ;
262331}
@@ -267,7 +336,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
267336
268337 if (down_interruptible (& efi_runtime_lock ))
269338 return EFI_ABORTED ;
270- status = efi_queue_work (EFI_SET_TIME , tm , NULL , NULL , NULL , NULL );
339+ status = efi_queue_work (SET_TIME , tm );
271340 up (& efi_runtime_lock );
272341 return status ;
273342}
@@ -280,8 +349,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
280349
281350 if (down_interruptible (& efi_runtime_lock ))
282351 return EFI_ABORTED ;
283- status = efi_queue_work (EFI_GET_WAKEUP_TIME , enabled , pending , tm , NULL ,
284- NULL );
352+ status = efi_queue_work (GET_WAKEUP_TIME , enabled , pending , tm );
285353 up (& efi_runtime_lock );
286354 return status ;
287355}
@@ -292,8 +360,7 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
292360
293361 if (down_interruptible (& efi_runtime_lock ))
294362 return EFI_ABORTED ;
295- status = efi_queue_work (EFI_SET_WAKEUP_TIME , & enabled , tm , NULL , NULL ,
296- NULL );
363+ status = efi_queue_work (SET_WAKEUP_TIME , enabled , tm );
297364 up (& efi_runtime_lock );
298365 return status ;
299366}
@@ -308,7 +375,7 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
308375
309376 if (down_interruptible (& efi_runtime_lock ))
310377 return EFI_ABORTED ;
311- status = efi_queue_work (EFI_GET_VARIABLE , name , vendor , attr , data_size ,
378+ status = efi_queue_work (GET_VARIABLE , name , vendor , attr , data_size ,
312379 data );
313380 up (& efi_runtime_lock );
314381 return status ;
@@ -322,8 +389,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
322389
323390 if (down_interruptible (& efi_runtime_lock ))
324391 return EFI_ABORTED ;
325- status = efi_queue_work (EFI_GET_NEXT_VARIABLE , name_size , name , vendor ,
326- NULL , NULL );
392+ status = efi_queue_work (GET_NEXT_VARIABLE , name_size , name , vendor );
327393 up (& efi_runtime_lock );
328394 return status ;
329395}
@@ -338,7 +404,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
338404
339405 if (down_interruptible (& efi_runtime_lock ))
340406 return EFI_ABORTED ;
341- status = efi_queue_work (EFI_SET_VARIABLE , name , vendor , & attr , & data_size ,
407+ status = efi_queue_work (SET_VARIABLE , name , vendor , attr , data_size ,
342408 data );
343409 up (& efi_runtime_lock );
344410 return status ;
@@ -373,8 +439,8 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
373439
374440 if (down_interruptible (& efi_runtime_lock ))
375441 return EFI_ABORTED ;
376- status = efi_queue_work (EFI_QUERY_VARIABLE_INFO , & attr , storage_space ,
377- remaining_space , max_variable_size , NULL );
442+ status = efi_queue_work (QUERY_VARIABLE_INFO , attr , storage_space ,
443+ remaining_space , max_variable_size );
378444 up (& efi_runtime_lock );
379445 return status ;
380446}
@@ -405,8 +471,7 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
405471
406472 if (down_interruptible (& efi_runtime_lock ))
407473 return EFI_ABORTED ;
408- status = efi_queue_work (EFI_GET_NEXT_HIGH_MONO_COUNT , count , NULL , NULL ,
409- NULL , NULL );
474+ status = efi_queue_work (GET_NEXT_HIGH_MONO_COUNT , count );
410475 up (& efi_runtime_lock );
411476 return status ;
412477}
@@ -437,8 +502,7 @@ static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
437502
438503 if (down_interruptible (& efi_runtime_lock ))
439504 return EFI_ABORTED ;
440- status = efi_queue_work (EFI_UPDATE_CAPSULE , capsules , & count , & sg_list ,
441- NULL , NULL );
505+ status = efi_queue_work (UPDATE_CAPSULE , capsules , count , sg_list );
442506 up (& efi_runtime_lock );
443507 return status ;
444508}
@@ -455,8 +519,8 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
455519
456520 if (down_interruptible (& efi_runtime_lock ))
457521 return EFI_ABORTED ;
458- status = efi_queue_work (EFI_QUERY_CAPSULE_CAPS , capsules , & count ,
459- max_size , reset_type , NULL );
522+ status = efi_queue_work (QUERY_CAPSULE_CAPS , capsules , count ,
523+ max_size , reset_type );
460524 up (& efi_runtime_lock );
461525 return status ;
462526}
0 commit comments