boot: add helper for converting EFI_PHYSICAL_ADDRESS to a pointer
This isn't trivial when trying to be compatible with 32bit archs, hence add a set of helper macro-like functions that make the conversion safe.
This commit is contained in:
+1
-1
@@ -452,7 +452,7 @@ EFI_STATUS pack_cpio(
|
||||
#if ENABLE_TPM
|
||||
err = tpm_log_event(
|
||||
tpm_pcr,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) buffer,
|
||||
POINTER_TO_PHYSICAL_ADDRESS(buffer),
|
||||
buffer_size,
|
||||
tpm_description);
|
||||
if (EFI_ERROR(err))
|
||||
|
||||
@@ -28,12 +28,6 @@ static UINTN devicetree_allocated(const struct devicetree_state *state) {
|
||||
return state->pages * EFI_PAGE_SIZE;
|
||||
}
|
||||
|
||||
static VOID *devicetree_ptr(const struct devicetree_state *state) {
|
||||
assert(state);
|
||||
assert(state->addr <= UINTN_MAX);
|
||||
return (VOID *)(UINTN)state->addr;
|
||||
}
|
||||
|
||||
static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
|
||||
EFI_DT_FIXUP_PROTOCOL *fixup;
|
||||
UINTN size;
|
||||
@@ -47,24 +41,24 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
|
||||
L"Could not locate device tree fixup protocol, skipping.");
|
||||
|
||||
size = devicetree_allocated(state);
|
||||
err = uefi_call_wrapper(fixup->Fixup, 4, fixup, devicetree_ptr(state), &size,
|
||||
err = uefi_call_wrapper(fixup->Fixup, 4, fixup, PHYSICAL_ADDRESS_TO_POINTER(state->addr), &size,
|
||||
EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY);
|
||||
if (err == EFI_BUFFER_TOO_SMALL) {
|
||||
EFI_PHYSICAL_ADDRESS oldaddr = state->addr;
|
||||
UINTN oldpages = state->pages;
|
||||
VOID *oldptr = devicetree_ptr(state);
|
||||
VOID *oldptr = PHYSICAL_ADDRESS_TO_POINTER(state->addr);
|
||||
|
||||
err = devicetree_allocate(state, size);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
CopyMem(devicetree_ptr(state), oldptr, len);
|
||||
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len);
|
||||
err = uefi_call_wrapper(BS->FreePages, 2, oldaddr, oldpages);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
size = devicetree_allocated(state);
|
||||
err = uefi_call_wrapper(fixup->Fixup, 4, fixup, devicetree_ptr(state), &size,
|
||||
err = uefi_call_wrapper(fixup->Fixup, 4, fixup, PHYSICAL_ADDRESS_TO_POINTER(state->addr), &size,
|
||||
EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY);
|
||||
}
|
||||
|
||||
@@ -104,7 +98,7 @@ EFI_STATUS devicetree_install(struct devicetree_state *state,
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
err = uefi_call_wrapper(handle->Read, 3, handle, &len, devicetree_ptr(state));
|
||||
err = uefi_call_wrapper(handle->Read, 3, handle, &len, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
@@ -112,7 +106,7 @@ EFI_STATUS devicetree_install(struct devicetree_state *state,
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, devicetree_ptr(state));
|
||||
return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
|
||||
}
|
||||
|
||||
void devicetree_cleanup(struct devicetree_state *state) {
|
||||
|
||||
@@ -66,9 +66,10 @@ EFI_STATUS linux_exec(EFI_HANDLE image,
|
||||
EFI_SIZE_TO_PAGES(cmdline_len + 1), &addr);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
CopyMem((VOID *)(UINTN)addr, cmdline, cmdline_len);
|
||||
((CHAR8 *)(UINTN)addr)[cmdline_len] = 0;
|
||||
boot_params->hdr.cmd_line_ptr = (UINT32)addr;
|
||||
|
||||
CopyMem(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
|
||||
((CHAR8 *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
|
||||
boot_params->hdr.cmd_line_ptr = (UINT32) addr;
|
||||
}
|
||||
|
||||
boot_params->hdr.ramdisk_image = (UINT32)initrd_addr;
|
||||
|
||||
@@ -168,7 +168,7 @@ EFI_STATUS tpm_log_load_options(const CHAR16 *load_options) {
|
||||
/* Measures a load options string into the TPM2, i.e. the kernel command line */
|
||||
|
||||
err = tpm_log_event(TPM_PCR_INDEX_KERNEL_PARAMETERS,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) load_options,
|
||||
POINTER_TO_PHYSICAL_ADDRESS(load_options),
|
||||
StrSize(load_options), load_options);
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement: %r", err);
|
||||
|
||||
+5
-5
@@ -55,13 +55,13 @@ static EFI_STATUS combine_initrd(
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to allocate space for combined initrd: %r", err);
|
||||
|
||||
p = (UINT8*) (UINTN) base;
|
||||
p = PHYSICAL_ADDRESS_TO_POINTER(base);
|
||||
if (initrd_base != 0) {
|
||||
UINTN pad;
|
||||
|
||||
/* Order matters, the real initrd must come first, since it might include microcode updates
|
||||
* which the kernel only looks for in the first cpio archive */
|
||||
CopyMem(p, (VOID*) (UINTN) initrd_base, initrd_size);
|
||||
CopyMem(p, PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
|
||||
p += initrd_size;
|
||||
|
||||
pad = ALIGN_TO(initrd_size, 4) - initrd_size;
|
||||
@@ -81,7 +81,7 @@ static EFI_STATUS combine_initrd(
|
||||
p += sysext_initrd_size;
|
||||
}
|
||||
|
||||
assert((UINT8*) (UINTN) base + n == p);
|
||||
assert((UINT8*) PHYSICAL_ADDRESS_TO_POINTER(base) + n == p);
|
||||
|
||||
*ret_initrd_base = base;
|
||||
*ret_initrd_size = n;
|
||||
@@ -222,10 +222,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
&sysext_initrd,
|
||||
&sysext_initrd_size);
|
||||
|
||||
linux_base = (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->ImageBase + addrs[SECTION_LINUX];
|
||||
linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_LINUX];
|
||||
|
||||
initrd_size = szs[SECTION_INITRD];
|
||||
initrd_base = initrd_size != 0 ? (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->ImageBase + addrs[SECTION_INITRD] : 0;
|
||||
initrd_base = initrd_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_INITRD] : 0;
|
||||
|
||||
if (credential_initrd || sysext_initrd) {
|
||||
/* If we have generated initrds dynamically, let's combine them with the built-in initrd. */
|
||||
|
||||
@@ -124,3 +124,23 @@ static inline void strv_freep(CHAR16 ***p) {
|
||||
}
|
||||
|
||||
EFI_STATUS open_directory(EFI_FILE_HANDLE root_dir, const CHAR16 *path, EFI_FILE_HANDLE *ret);
|
||||
|
||||
/* Conversion between EFI_PHYSICAL_ADDRESS and pointers is not obvious. The former is always 64bit, even on
|
||||
* 32bit archs. And gcc complains if we cast a pointer to an integer of a different size. Hence let's do the
|
||||
* conversion indirectly: first into UINTN (which is defined by UEFI to have the same size as a pointer), and
|
||||
* then extended to EFI_PHYSICAL_ADDRESS. */
|
||||
static inline EFI_PHYSICAL_ADDRESS POINTER_TO_PHYSICAL_ADDRESS(const void *p) {
|
||||
return (EFI_PHYSICAL_ADDRESS) (UINTN) p;
|
||||
}
|
||||
|
||||
static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr) {
|
||||
#if __SIZEOF_POINTER__ == 4
|
||||
/* On 32bit systems the address might not be convertible (as pointers are 32bit but
|
||||
* EFI_PHYSICAL_ADDRESS 64bit) */
|
||||
assert(addr <= UINT32_MAX);
|
||||
#elif __SIZEOF_POINTER__ != 8
|
||||
#error "Unexpected pointer size"
|
||||
#endif
|
||||
|
||||
return (void*) (UINTN) addr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user