[U-Boot] [PATCH v2] efi_loader: Make RTS relocation more robust
Jonathan Gray
jsg at jsg.id.au
Fri Dec 14 01:15:37 UTC 2018
On Tue, Dec 11, 2018 at 10:00:42AM +0100, Alexander Graf wrote:
> While changing the RTS alignment to 64KB in commit 7a82c3051c8f
> ("efi_loader: Align runtime section to 64kb") the relocation code
> started to break.
>
> The reason for that is that we didn't actually look at the real
> relocation data. We merely took the RUNTIME_CODE section as a
> hint and started to relocate based on self calculated data from
> that point on. That calculation was now out of sync though.
>
> To ensure we're not running into such a situation again, this patch
> makes the runtime relocation code a bit more robust. We can just
> trust the phys/virt hints from the payload. We also should check that
> we really only have a single section, as the code doesn't handle
> multiple code relocations yet.
>
> Fixes: 7a82c3051c8f ("efi_loader: Align runtime section to 64kb")
> Reported-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> Reported-by: Loic Devulder <ldevulder at suse.de>
> Signed-off-by: Alexander Graf <agraf at suse.de>
This fixes booting OpenBSD on qemu-system-aarch64 where previously it
would drop into the kernel debugger when probing efi runtime services.
Tested-by: Jonathan Gray <jsg at jsg.id.au>
>
> ---
>
> v1 -> v2:
>
> - Add more verbose comment explaining why we have the
> sanity check.
> ---
> lib/efi_loader/efi_runtime.c | 34 +++++++++++++++++++++++++++++++---
> 1 file changed, 31 insertions(+), 3 deletions(-)
>
> diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
> index 95844efdb0..fff93f0960 100644
> --- a/lib/efi_loader/efi_runtime.c
> +++ b/lib/efi_loader/efi_runtime.c
> @@ -436,14 +436,42 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
> uint32_t descriptor_version,
> struct efi_mem_desc *virtmap)
> {
> - ulong runtime_start = (ulong)&__efi_runtime_start &
> - ~(ulong)EFI_PAGE_MASK;
> int n = memory_map_size / descriptor_size;
> int i;
> + int rt_code_sections = 0;
>
> EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size,
> descriptor_version, virtmap);
>
> + /*
> + * TODO:
> + * Further down we are cheating. While really we should implement
> + * SetVirtualAddressMap() events and ConvertPointer() to allow
> + * dynamically loaded drivers to expose runtime services, we don't
> + * today.
> + *
> + * So let's ensure we see exactly one single runtime section, as
> + * that is the built-in one. If we see more (or less), someone must
> + * have tried adding or removing to that which we don't support yet.
> + * In that case, let's better fail rather than expose broken runtime
> + * services.
> + */
> + for (i = 0; i < n; i++) {
> + struct efi_mem_desc *map = (void*)virtmap +
> + (descriptor_size * i);
> +
> + if (map->type == EFI_RUNTIME_SERVICES_CODE)
> + rt_code_sections++;
> + }
> +
> + if (rt_code_sections != 1) {
> + /*
> + * We expose exactly one single runtime code section, so
> + * something is definitely going wrong.
> + */
> + return EFI_EXIT(EFI_INVALID_PARAMETER);
> + }
> +
> /* Rebind mmio pointers */
> for (i = 0; i < n; i++) {
> struct efi_mem_desc *map = (void*)virtmap +
> @@ -483,7 +511,7 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
> map = (void*)virtmap + (descriptor_size * i);
> if (map->type == EFI_RUNTIME_SERVICES_CODE) {
> ulong new_offset = map->virtual_start -
> - (runtime_start - gd->relocaddr);
> + map->physical_start + gd->relocaddr;
>
> efi_runtime_relocate(new_offset, map);
> /* Once we're virtual, we can no longer handle
> --
> 2.12.3
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
More information about the U-Boot
mailing list