44
44
#define __efi_call_virt (f , args ...) \
45
45
__efi_call_virt_pointer(efi.runtime, f, args)
46
46
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
+
47
115
struct efi_runtime_work efi_rts_work ;
48
116
49
117
/*
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
53
121
*
54
122
* Accesses to efi_runtime_services() are serialized by a binary
55
123
* semaphore (efi_runtime_lock) and caller waits until the work is
56
124
* finished, hence _only_ one work is queued at a time and the caller
57
125
* thread waits for completion.
58
126
*/
59
- #define efi_queue_work (_rts , _arg1 , _arg2 , _arg3 , _arg4 , _arg5 ) \
127
+ #define efi_queue_work (_rts , _args ...) \
60
128
({ \
129
+ efi_rts_work.efi_rts_id = EFI_ ## _rts; \
130
+ efi_rts_work.args = &(union efi_rts_args){ ._rts = { _args }}; \
61
131
efi_rts_work.status = EFI_ABORTED; \
62
132
\
63
133
if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \
@@ -68,12 +138,6 @@ struct efi_runtime_work efi_rts_work;
68
138
\
69
139
init_completion(&efi_rts_work.efi_rts_comp); \
70
140
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; \
77
141
\
78
142
/* \
79
143
* 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);
170
234
/*
171
235
* Calls the appropriate efi_runtime_service() with the appropriate
172
236
* 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.
179
237
*/
180
238
static void efi_call_rts (struct work_struct * work )
181
239
{
182
- void * arg1 , * arg2 , * arg3 , * arg4 , * arg5 ;
240
+ const union efi_rts_args * args = efi_rts_work . args ;
183
241
efi_status_t status = EFI_NOT_FOUND ;
184
242
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
-
191
243
switch (efi_rts_work .efi_rts_id ) {
192
244
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 );
195
248
break ;
196
249
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 );
198
252
break ;
199
253
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 );
202
258
break ;
203
259
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 );
206
263
break ;
207
264
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 );
211
271
break ;
212
272
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 );
216
277
break ;
217
278
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 );
221
285
break ;
222
286
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 );
225
292
break ;
226
293
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 );
228
296
break ;
229
297
case EFI_UPDATE_CAPSULE :
230
298
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 );
234
302
break ;
235
303
case EFI_QUERY_CAPSULE_CAPS :
236
304
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 );
240
309
break ;
241
310
default :
242
311
/*
@@ -256,7 +325,7 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
256
325
257
326
if (down_interruptible (& efi_runtime_lock ))
258
327
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 );
260
329
up (& efi_runtime_lock );
261
330
return status ;
262
331
}
@@ -267,7 +336,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
267
336
268
337
if (down_interruptible (& efi_runtime_lock ))
269
338
return EFI_ABORTED ;
270
- status = efi_queue_work (EFI_SET_TIME , tm , NULL , NULL , NULL , NULL );
339
+ status = efi_queue_work (SET_TIME , tm );
271
340
up (& efi_runtime_lock );
272
341
return status ;
273
342
}
@@ -280,8 +349,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
280
349
281
350
if (down_interruptible (& efi_runtime_lock ))
282
351
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 );
285
353
up (& efi_runtime_lock );
286
354
return status ;
287
355
}
@@ -292,8 +360,7 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
292
360
293
361
if (down_interruptible (& efi_runtime_lock ))
294
362
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 );
297
364
up (& efi_runtime_lock );
298
365
return status ;
299
366
}
@@ -308,7 +375,7 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
308
375
309
376
if (down_interruptible (& efi_runtime_lock ))
310
377
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 ,
312
379
data );
313
380
up (& efi_runtime_lock );
314
381
return status ;
@@ -322,8 +389,7 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
322
389
323
390
if (down_interruptible (& efi_runtime_lock ))
324
391
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 );
327
393
up (& efi_runtime_lock );
328
394
return status ;
329
395
}
@@ -338,7 +404,7 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
338
404
339
405
if (down_interruptible (& efi_runtime_lock ))
340
406
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 ,
342
408
data );
343
409
up (& efi_runtime_lock );
344
410
return status ;
@@ -373,8 +439,8 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
373
439
374
440
if (down_interruptible (& efi_runtime_lock ))
375
441
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 );
378
444
up (& efi_runtime_lock );
379
445
return status ;
380
446
}
@@ -405,8 +471,7 @@ static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
405
471
406
472
if (down_interruptible (& efi_runtime_lock ))
407
473
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 );
410
475
up (& efi_runtime_lock );
411
476
return status ;
412
477
}
@@ -437,8 +502,7 @@ static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
437
502
438
503
if (down_interruptible (& efi_runtime_lock ))
439
504
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 );
442
506
up (& efi_runtime_lock );
443
507
return status ;
444
508
}
@@ -455,8 +519,8 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
455
519
456
520
if (down_interruptible (& efi_runtime_lock ))
457
521
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 );
460
524
up (& efi_runtime_lock );
461
525
return status ;
462
526
}
0 commit comments