To handle all arch-specific peculiarities when calling an EFI protocol function, a wrapper efi_call_proto() exists on all relevant architectures. On arm/arm64, this is merely a plain function call. On x86, a special EFI entry stub needs to be used, however, as the calling convention differs. To make the efi/random stub arch-independent, use efi_call_proto() instead of the existing non-portable calls to the EFI get_rng protocol function. This also requires the addition of some typedefs.
Unified · Split
| @@ -9,6 +9,18 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include "efistub.h" | 10 | #include "efistub.h" |
| 11 | 11 | ||
| 12 | typedef struct efi_rng_protocol efi_rng_protocol_t; | ||
| 13 | |||
| 14 | typedef struct { | ||
| 15 | u32 get_info; | ||
| 16 | u32 get_rng; | ||
| 17 | } efi_rng_protocol_32_t; | ||
| 18 | |||
| 19 | typedef struct { | ||
| 20 | u64 get_info; | ||
| 21 | u64 get_rng; | ||
| 22 | } efi_rng_protocol_64_t; | ||
| 23 | |||
| 12 | struct efi_rng_protocol { | 24 | struct efi_rng_protocol { |
| 13 | efi_status_t (*get_info)(struct efi_rng_protocol *, | 25 | efi_status_t (*get_info)(struct efi_rng_protocol *, |
| 14 | unsigned long *, efi_guid_t *); | 26 | unsigned long *, efi_guid_t *); |
| @@ -28,7 +40,7 @@ efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg, · 13 unmodified lines | |||
| 28 | if (status != EFI_SUCCESS) | 40 | if (status != EFI_SUCCESS) |
| 29 | return status; | 41 | return status; |
| 30 | 42 | ||
| 31 | return rng->get_rng(rng, NULL, size, out); | 43 | return efi_call_proto(efi_rng_protocol, get_rng, rng, NULL, size, out); |
| 32 | } | 44 | } |
| 33 | 45 | ||
| 34 | /* | 46 | /* |
| @@ -161,15 +173,16 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg) · 126 unmodified lines | |||
| 161 | if (status != EFI_SUCCESS) | 173 | if (status != EFI_SUCCESS) |
| 162 | return status; | 174 | return status; |
| 163 | 175 | ||
| 164 | status = rng->get_rng(rng, &rng_algo_raw, EFI_RANDOM_SEED_SIZE, | 176 | status = efi_call_proto(efi_rng_protocol, get_rng, rng, &rng_algo_raw, |
| 165 | seed->bits); | 177 | EFI_RANDOM_SEED_SIZE, seed->bits); |
| 178 | |||
| 166 | if (status == EFI_UNSUPPORTED) | 179 | if (status == EFI_UNSUPPORTED) |
| 167 | /* | 180 | /* |
| 168 | * Use whatever algorithm we have available if the raw algorithm | 181 | * Use whatever algorithm we have available if the raw algorithm |
| 169 | * is not implemented. | 182 | * is not implemented. |
| 170 | */ | 183 | */ |
| 171 | status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE, | 184 | status = efi_call_proto(efi_rng_protocol, get_rng, rng, NULL, |
| 172 | seed->bits); | 185 | EFI_RANDOM_SEED_SIZE, seed->bits); |
| 173 | 186 | ||
| 174 | if (status != EFI_SUCCESS) | 187 | if (status != EFI_SUCCESS) |
| 175 | goto err_freepool; | 188 | goto err_freepool; |