4242#define efi_call_virt (f , args ...) \
4343 efi_call_virt_pointer(efi.runtime, f, args)
4444
45+ union efi_rts_args {
46+ struct {
47+ efi_time_t * time ;
48+ efi_time_cap_t * capabilities ;
49+ } GET_TIME ;
50+
51+ struct {
52+ efi_time_t * time ;
53+ } SET_TIME ;
54+
55+ struct {
56+ efi_bool_t * enabled ;
57+ efi_bool_t * pending ;
58+ efi_time_t * time ;
59+ } GET_WAKEUP_TIME ;
60+
61+ struct {
62+ efi_bool_t enable ;
63+ efi_time_t * time ;
64+ } SET_WAKEUP_TIME ;
65+
66+ struct {
67+ efi_char16_t * name ;
68+ efi_guid_t * vendor ;
69+ u32 * attr ;
70+ unsigned long * data_size ;
71+ void * data ;
72+ } GET_VARIABLE ;
73+
74+ struct {
75+ unsigned long * name_size ;
76+ efi_char16_t * name ;
77+ efi_guid_t * vendor ;
78+ } GET_NEXT_VARIABLE ;
79+
80+ struct {
81+ efi_char16_t * name ;
82+ efi_guid_t * vendor ;
83+ u32 attr ;
84+ unsigned long data_size ;
85+ void * data ;
86+ } SET_VARIABLE ;
87+
88+ struct {
89+ u32 attr ;
90+ u64 * storage_space ;
91+ u64 * remaining_space ;
92+ u64 * max_variable_size ;
93+ } QUERY_VARIABLE_INFO ;
94+
95+ struct {
96+ u32 * high_count ;
97+ } GET_NEXT_HIGH_MONO_COUNT ;
98+
99+ struct {
100+ efi_capsule_header_t * * capsules ;
101+ unsigned long count ;
102+ unsigned long sg_list ;
103+ } UPDATE_CAPSULE ;
104+
105+ struct {
106+ efi_capsule_header_t * * capsules ;
107+ unsigned long count ;
108+ u64 * max_size ;
109+ int * reset_type ;
110+ } QUERY_CAPSULE_CAPS ;
111+ };
112+
45113struct efi_runtime_work efi_rts_work ;
46114
47115/*
48- * efi_queue_work: Queue efi_runtime_service() and wait until it's done
49- * @rts : efi_runtime_service() function identifier
50- * @rts_arg<1-5>: efi_runtime_service() function arguments
116+ * efi_queue_work: Queue EFI runtime service call and wait for completion
117+ * @_rts : EFI runtime service function identifier
118+ * @_args: Arguments to pass to the EFI runtime service
51119 *
52120 * Accesses to efi_runtime_services() are serialized by a binary
53121 * semaphore (efi_runtime_lock) and caller waits until the work is
54122 * finished, hence _only_ one work is queued at a time and the caller
55123 * thread waits for completion.
56124 */
57- #define efi_queue_work (_rts , _arg1 , _arg2 , _arg3 , _arg4 , _arg5 ) \
125+ #define efi_queue_work (_rts , _args ...) \
58126({ \
127+ efi_rts_work.efi_rts_id = EFI_ ## _rts; \
128+ efi_rts_work.args = &(union efi_rts_args){ ._rts = { _args }}; \
59129 efi_rts_work.status = EFI_ABORTED; \
60130 \
61131 if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \
@@ -66,12 +136,6 @@ struct efi_runtime_work efi_rts_work;
66136 \
67137 init_completion(&efi_rts_work.efi_rts_comp); \
68138 INIT_WORK(&efi_rts_work.work, efi_call_rts); \
69- efi_rts_work.arg1 = _arg1; \
70- efi_rts_work.arg2 = _arg2; \
71- efi_rts_work.arg3 = _arg3; \
72- efi_rts_work.arg4 = _arg4; \
73- efi_rts_work.arg5 = _arg5; \
74- efi_rts_work.efi_rts_id = _rts; \
75139 \
76140 /* \
77141 * queue_work() returns 0 if work was already on queue, \
@@ -168,73 +232,78 @@ extern struct semaphore __efi_uv_runtime_lock __alias(efi_runtime_lock);
168232/*
169233 * Calls the appropriate efi_runtime_service() with the appropriate
170234 * arguments.
171- *
172- * Semantics followed by efi_call_rts() to understand efi_runtime_work:
173- * 1. If argument was a pointer, recast it from void pointer to original
174- * pointer type.
175- * 2. If argument was a value, recast it from void pointer to original
176- * pointer type and dereference it.
177235 */
178236static void efi_call_rts (struct work_struct * work )
179237{
180- void * arg1 , * arg2 , * arg3 , * arg4 , * arg5 ;
238+ const union efi_rts_args * args = efi_rts_work . args ;
181239 efi_status_t status = EFI_NOT_FOUND ;
182240
183- arg1 = efi_rts_work .arg1 ;
184- arg2 = efi_rts_work .arg2 ;
185- arg3 = efi_rts_work .arg3 ;
186- arg4 = efi_rts_work .arg4 ;
187- arg5 = efi_rts_work .arg5 ;
188-
189241 switch (efi_rts_work .efi_rts_id ) {
190242 case EFI_GET_TIME :
191- status = efi_call_virt (get_time , (efi_time_t * )arg1 ,
192- (efi_time_cap_t * )arg2 );
243+ status = efi_call_virt (get_time ,
244+ args -> GET_TIME .time ,
245+ args -> GET_TIME .capabilities );
193246 break ;
194247 case EFI_SET_TIME :
195- status = efi_call_virt (set_time , (efi_time_t * )arg1 );
248+ status = efi_call_virt (set_time ,
249+ args -> SET_TIME .time );
196250 break ;
197251 case EFI_GET_WAKEUP_TIME :
198- status = efi_call_virt (get_wakeup_time , (efi_bool_t * )arg1 ,
199- (efi_bool_t * )arg2 , (efi_time_t * )arg3 );
252+ status = efi_call_virt (get_wakeup_time ,
253+ args -> GET_WAKEUP_TIME .enabled ,
254+ args -> GET_WAKEUP_TIME .pending ,
255+ args -> GET_WAKEUP_TIME .time );
200256 break ;
201257 case EFI_SET_WAKEUP_TIME :
202- status = efi_call_virt (set_wakeup_time , * (efi_bool_t * )arg1 ,
203- (efi_time_t * )arg2 );
258+ status = efi_call_virt (set_wakeup_time ,
259+ args -> SET_WAKEUP_TIME .enable ,
260+ args -> SET_WAKEUP_TIME .time );
204261 break ;
205262 case EFI_GET_VARIABLE :
206- status = efi_call_virt (get_variable , (efi_char16_t * )arg1 ,
207- (efi_guid_t * )arg2 , (u32 * )arg3 ,
208- (unsigned long * )arg4 , (void * )arg5 );
263+ status = efi_call_virt (get_variable ,
264+ args -> GET_VARIABLE .name ,
265+ args -> GET_VARIABLE .vendor ,
266+ args -> GET_VARIABLE .attr ,
267+ args -> GET_VARIABLE .data_size ,
268+ args -> GET_VARIABLE .data );
209269 break ;
210270 case EFI_GET_NEXT_VARIABLE :
211- status = efi_call_virt (get_next_variable , (unsigned long * )arg1 ,
212- (efi_char16_t * )arg2 ,
213- (efi_guid_t * )arg3 );
271+ status = efi_call_virt (get_next_variable ,
272+ args -> GET_NEXT_VARIABLE .name_size ,
273+ args -> GET_NEXT_VARIABLE .name ,
274+ args -> GET_NEXT_VARIABLE .vendor );
214275 break ;
215276 case EFI_SET_VARIABLE :
216- status = efi_call_virt (set_variable , (efi_char16_t * )arg1 ,
217- (efi_guid_t * )arg2 , * (u32 * )arg3 ,
218- * (unsigned long * )arg4 , (void * )arg5 );
277+ status = efi_call_virt (set_variable ,
278+ args -> SET_VARIABLE .name ,
279+ args -> SET_VARIABLE .vendor ,
280+ args -> SET_VARIABLE .attr ,
281+ args -> SET_VARIABLE .data_size ,
282+ args -> SET_VARIABLE .data );
219283 break ;
220284 case EFI_QUERY_VARIABLE_INFO :
221- status = efi_call_virt (query_variable_info , * (u32 * )arg1 ,
222- (u64 * )arg2 , (u64 * )arg3 , (u64 * )arg4 );
285+ status = efi_call_virt (query_variable_info ,
286+ args -> QUERY_VARIABLE_INFO .attr ,
287+ args -> QUERY_VARIABLE_INFO .storage_space ,
288+ args -> QUERY_VARIABLE_INFO .remaining_space ,
289+ args -> QUERY_VARIABLE_INFO .max_variable_size );
223290 break ;
224291 case EFI_GET_NEXT_HIGH_MONO_COUNT :
225- status = efi_call_virt (get_next_high_mono_count , (u32 * )arg1 );
292+ status = efi_call_virt (get_next_high_mono_count ,
293+ args -> GET_NEXT_HIGH_MONO_COUNT .high_count );
226294 break ;
227295 case EFI_UPDATE_CAPSULE :
228296 status = efi_call_virt (update_capsule ,
229- ( efi_capsule_header_t * * ) arg1 ,
230- * ( unsigned long * ) arg2 ,
231- * ( unsigned long * ) arg3 );
297+ args -> UPDATE_CAPSULE . capsules ,
298+ args -> UPDATE_CAPSULE . count ,
299+ args -> UPDATE_CAPSULE . sg_list );
232300 break ;
233301 case EFI_QUERY_CAPSULE_CAPS :
234302 status = efi_call_virt (query_capsule_caps ,
235- (efi_capsule_header_t * * )arg1 ,
236- * (unsigned long * )arg2 , (u64 * )arg3 ,
237- (int * )arg4 );
303+ args -> QUERY_CAPSULE_CAPS .capsules ,
304+ args -> QUERY_CAPSULE_CAPS .count ,
305+ args -> QUERY_CAPSULE_CAPS .max_size ,
306+ args -> QUERY_CAPSULE_CAPS .reset_type );
238307 break ;
239308 default :
240309 /*
@@ -254,7 +323,7 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
254323
255324 if (down_interruptible (& efi_runtime_lock ))
256325 return EFI_ABORTED ;
257- status = efi_queue_work (EFI_GET_TIME , tm , tc , NULL , NULL , NULL );
326+ status = efi_queue_work (GET_TIME , tm , tc );
258327 up (& efi_runtime_lock );
259328 return status ;
260329}
@@ -265,7 +334,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
265334
266335 if (down_interruptible (& efi_runtime_lock ))
267336 return EFI_ABORTED ;
268- status = efi_queue_work (EFI_SET_TIME , tm , NULL , NULL , NULL , NULL );
337+ status = efi_queue_work (SET_TIME , tm );
269338 up (& efi_runtime_lock );
270339 return status ;
271340}
@@ -278,8 +347,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
278347
279348 if (down_interruptible (& efi_runtime_lock ))
280349 return EFI_ABORTED ;
281- status = efi_queue_work (EFI_GET_WAKEUP_TIME , enabled , pending , tm , NULL ,
282- NULL );
350+ status = efi_queue_work (GET_WAKEUP_TIME , enabled , pending , tm );
283351 up (& efi_runtime_lock );
284352 return status ;
285353}
@@ -290,8 +358,7 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
290358
291359 if (down_interruptible (& efi_runtime_lock ))
292360 return EFI_ABORTED ;
293- status = efi_queue_work (EFI_SET_WAKEUP_TIME , & enabled , tm , NULL , NULL ,
294- NULL );
361+ status = efi_queue_work (SET_WAKEUP_TIME , enabled , tm );
295362 up (& efi_runtime_lock );
296363 return status ;
297364}
@@ -306,7 +373,7 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
306373
307374 if (down_interruptible (& efi_runtime_lock ))
308375 return EFI_ABORTED ;
309- status = efi_queue_work (EFI_GET_VARIABLE , name , vendor , attr , data_size ,
376+ status = efi_queue_work (GET_VARIABLE , name , vendor , attr , data_size ,
310377 data );
311378 up (& efi_runtime_lock );
312379 return status ;
@@ -320,8 +387,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
320387
321388 if (down_interruptible (& efi_runtime_lock ))
322389 return EFI_ABORTED ;
323- status = efi_queue_work (EFI_GET_NEXT_VARIABLE , name_size , name , vendor ,
324- NULL , NULL );
390+ status = efi_queue_work (GET_NEXT_VARIABLE , name_size , name , vendor );
325391 up (& efi_runtime_lock );
326392 return status ;
327393}
@@ -336,7 +402,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
336402
337403 if (down_interruptible (& efi_runtime_lock ))
338404 return EFI_ABORTED ;
339- status = efi_queue_work (EFI_SET_VARIABLE , name , vendor , & attr , & data_size ,
405+ status = efi_queue_work (SET_VARIABLE , name , vendor , attr , data_size ,
340406 data );
341407 up (& efi_runtime_lock );
342408 return status ;
@@ -371,8 +437,8 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
371437
372438 if (down_interruptible (& efi_runtime_lock ))
373439 return EFI_ABORTED ;
374- status = efi_queue_work (EFI_QUERY_VARIABLE_INFO , & attr , storage_space ,
375- remaining_space , max_variable_size , NULL );
440+ status = efi_queue_work (QUERY_VARIABLE_INFO , attr , storage_space ,
441+ remaining_space , max_variable_size );
376442 up (& efi_runtime_lock );
377443 return status ;
378444}
@@ -403,8 +469,7 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
403469
404470 if (down_interruptible (& efi_runtime_lock ))
405471 return EFI_ABORTED ;
406- status = efi_queue_work (EFI_GET_NEXT_HIGH_MONO_COUNT , count , NULL , NULL ,
407- NULL , NULL );
472+ status = efi_queue_work (GET_NEXT_HIGH_MONO_COUNT , count );
408473 up (& efi_runtime_lock );
409474 return status ;
410475}
@@ -440,8 +505,7 @@ static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
440505
441506 if (down_interruptible (& efi_runtime_lock ))
442507 return EFI_ABORTED ;
443- status = efi_queue_work (EFI_UPDATE_CAPSULE , capsules , & count , & sg_list ,
444- NULL , NULL );
508+ status = efi_queue_work (UPDATE_CAPSULE , capsules , count , sg_list );
445509 up (& efi_runtime_lock );
446510 return status ;
447511}
@@ -458,8 +522,8 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
458522
459523 if (down_interruptible (& efi_runtime_lock ))
460524 return EFI_ABORTED ;
461- status = efi_queue_work (EFI_QUERY_CAPSULE_CAPS , capsules , & count ,
462- max_size , reset_type , NULL );
525+ status = efi_queue_work (QUERY_CAPSULE_CAPS , capsules , count ,
526+ max_size , reset_type );
463527 up (& efi_runtime_lock );
464528 return status ;
465529}
0 commit comments