Commit beb077a2a8201c4b215d82e58c4d1d8ec8e48b58

Authored by Alexander Graf
1 parent c034bfab29

efi_loader: Introduce ms abi vararg helpers

Varargs differ between sysv and ms abi. On x86_64 we have to follow the ms
abi though, so we also need to make sure we use x86_64 varargs helpers.

This patch introduces generic efi vararg helpers that adhere to the
respective EFI ABI. That way we can deal with them properly from efi
loader code and properly interpret variable arguments.

This fixes the InstallMultipleProtocolInterfaces tests in the efi selftests
on x86_64 for me.

Signed-off-by: Alexander Graf <agraf@suse.de>

Showing 2 changed files with 26 additions and 18 deletions Side-by-side Diff

... ... @@ -29,8 +29,16 @@
29 29 */
30 30 #ifdef __x86_64__
31 31 #define EFIAPI __attribute__((ms_abi))
  32 +#define efi_va_list __builtin_ms_va_list
  33 +#define efi_va_start __builtin_ms_va_start
  34 +#define efi_va_arg __builtin_va_arg
  35 +#define efi_va_end __builtin_ms_va_end
32 36 #else
33 37 #define EFIAPI asmlinkage
  38 +#define efi_va_list va_list
  39 +#define efi_va_start va_start
  40 +#define efi_va_arg va_arg
  41 +#define efi_va_end va_end
34 42 #endif /* __x86_64__ */
35 43  
36 44 struct efi_device_path;
lib/efi_loader/efi_boottime.c
... ... @@ -2302,7 +2302,7 @@
2302 2302 {
2303 2303 EFI_ENTRY("%p", handle);
2304 2304  
2305   - va_list argptr;
  2305 + efi_va_list argptr;
2306 2306 const efi_guid_t *protocol;
2307 2307 void *protocol_interface;
2308 2308 efi_status_t r = EFI_SUCCESS;
2309 2309  
2310 2310  
... ... @@ -2311,12 +2311,12 @@
2311 2311 if (!handle)
2312 2312 return EFI_EXIT(EFI_INVALID_PARAMETER);
2313 2313  
2314   - va_start(argptr, handle);
  2314 + efi_va_start(argptr, handle);
2315 2315 for (;;) {
2316   - protocol = va_arg(argptr, efi_guid_t*);
  2316 + protocol = efi_va_arg(argptr, efi_guid_t*);
2317 2317 if (!protocol)
2318 2318 break;
2319   - protocol_interface = va_arg(argptr, void*);
  2319 + protocol_interface = efi_va_arg(argptr, void*);
2320 2320 r = EFI_CALL(efi_install_protocol_interface(
2321 2321 handle, protocol,
2322 2322 EFI_NATIVE_INTERFACE,
2323 2323  
2324 2324  
2325 2325  
... ... @@ -2325,19 +2325,19 @@
2325 2325 break;
2326 2326 i++;
2327 2327 }
2328   - va_end(argptr);
  2328 + efi_va_end(argptr);
2329 2329 if (r == EFI_SUCCESS)
2330 2330 return EFI_EXIT(r);
2331 2331  
2332 2332 /* If an error occurred undo all changes. */
2333   - va_start(argptr, handle);
  2333 + efi_va_start(argptr, handle);
2334 2334 for (; i; --i) {
2335   - protocol = va_arg(argptr, efi_guid_t*);
2336   - protocol_interface = va_arg(argptr, void*);
  2335 + protocol = efi_va_arg(argptr, efi_guid_t*);
  2336 + protocol_interface = efi_va_arg(argptr, void*);
2337 2337 EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
2338 2338 protocol_interface));
2339 2339 }
2340   - va_end(argptr);
  2340 + efi_va_end(argptr);
2341 2341  
2342 2342 return EFI_EXIT(r);
2343 2343 }
... ... @@ -2361,7 +2361,7 @@
2361 2361 {
2362 2362 EFI_ENTRY("%p", handle);
2363 2363  
2364   - va_list argptr;
  2364 + efi_va_list argptr;
2365 2365 const efi_guid_t *protocol;
2366 2366 void *protocol_interface;
2367 2367 efi_status_t r = EFI_SUCCESS;
2368 2368  
2369 2369  
... ... @@ -2370,12 +2370,12 @@
2370 2370 if (!handle)
2371 2371 return EFI_EXIT(EFI_INVALID_PARAMETER);
2372 2372  
2373   - va_start(argptr, handle);
  2373 + efi_va_start(argptr, handle);
2374 2374 for (;;) {
2375   - protocol = va_arg(argptr, efi_guid_t*);
  2375 + protocol = efi_va_arg(argptr, efi_guid_t*);
2376 2376 if (!protocol)
2377 2377 break;
2378   - protocol_interface = va_arg(argptr, void*);
  2378 + protocol_interface = efi_va_arg(argptr, void*);
2379 2379 r = EFI_CALL(efi_uninstall_protocol_interface(
2380 2380 handle, protocol,
2381 2381 protocol_interface));
2382 2382  
2383 2383  
2384 2384  
... ... @@ -2383,20 +2383,20 @@
2383 2383 break;
2384 2384 i++;
2385 2385 }
2386   - va_end(argptr);
  2386 + efi_va_end(argptr);
2387 2387 if (r == EFI_SUCCESS)
2388 2388 return EFI_EXIT(r);
2389 2389  
2390 2390 /* If an error occurred undo all changes. */
2391   - va_start(argptr, handle);
  2391 + efi_va_start(argptr, handle);
2392 2392 for (; i; --i) {
2393   - protocol = va_arg(argptr, efi_guid_t*);
2394   - protocol_interface = va_arg(argptr, void*);
  2393 + protocol = efi_va_arg(argptr, efi_guid_t*);
  2394 + protocol_interface = efi_va_arg(argptr, void*);
2395 2395 EFI_CALL(efi_install_protocol_interface(&handle, protocol,
2396 2396 EFI_NATIVE_INTERFACE,
2397 2397 protocol_interface));
2398 2398 }
2399   - va_end(argptr);
  2399 + efi_va_end(argptr);
2400 2400  
2401 2401 return EFI_EXIT(r);
2402 2402 }