On 1/30/19 11:46 AM, Alexander Graf wrote: > While discussing something compeltely different, Ard pointed out > that it might be legal to omit calling SetVirtualAddressMap altogether. > > There is even a patch on the Linux Kernel Mailing List that implements > such behavior by now: > > https://patchwork.kernel.org/patch/10782393/ > > While that sounds great, we currently rely on the SetVirtualAddressMap > call to remove all references to code that would not workoutside of > boot services. > > So let's patch out those bits already on the call to ExitBootServices, > so that we can successfully run even when an OS chooses to omit > any call to SetVirtualAddressMap. > > Reported-by: Ard Biesheuvel <ard.biesheu...@linaro.org> > Signed-off-by: Alexander Graf <ag...@suse.de> > > --- >
This patch series leads to a Python test error on qemu_arm64_defconfig: if m != 0: > raise Exception('Reset failed during the EFI selftest') E Exception: Reset failed during the EFI selftest test/py/tests/test_efi_selftest.py:25: Exception <snip /> The output looks like: Preparing for reset. Press any key... U-Boot 2019.01-00458-gada5205aef (Jan 30 2019 - 19:47:02 +0100) DRAM: <snip /> Please, adjust test_efi_selftest(). Best regards Heinrich > v1 -> v2: > > - Add missing icache invalidation > > v2 -> v3: > > - Add link to upstream Linux patch > --- > include/efi_loader.h | 2 ++ > lib/efi_loader/efi_boottime.c | 1 + > lib/efi_loader/efi_runtime.c | 29 ++++++++++++++++++++--------- > 3 files changed, 23 insertions(+), 9 deletions(-) > > diff --git a/include/efi_loader.h b/include/efi_loader.h > index 9dd933dae7..2a40b09693 100644 > --- a/include/efi_loader.h > +++ b/include/efi_loader.h > @@ -310,6 +310,8 @@ void efi_save_gd(void); > void efi_restore_gd(void); > /* Call this to relocate the runtime section to an address space */ > void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map); > +/* Call this when we start to live in a runtime only world */ > +void efi_runtime_detach(ulong offset); > /* Call this to set the current device name */ > void efi_set_bootdev(const char *dev, const char *devnr, const char *path); > /* Add a new object to the object list. */ > diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c > index fc26d6adc1..8cb2979bab 100644 > --- a/lib/efi_loader/efi_boottime.c > +++ b/lib/efi_loader/efi_boottime.c > @@ -1917,6 +1917,7 @@ static efi_status_t EFIAPI > efi_exit_boot_services(efi_handle_t image_handle, > bootm_disable_interrupts(); > > /* Disable boot time services */ > + efi_runtime_detach((ulong)gd->relocaddr); > systab.con_in_handle = NULL; > systab.con_in = NULL; > systab.con_out_handle = NULL; > diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c > index 636dfdab39..17d22d429e 100644 > --- a/lib/efi_loader/efi_runtime.c > +++ b/lib/efi_loader/efi_runtime.c > @@ -276,16 +276,12 @@ struct efi_runtime_detach_list_struct { > void *patchto; > }; > > -static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] > = { > +static struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = { > { > /* do_reset is gone */ > .ptr = &efi_runtime_services.reset_system, > .patchto = efi_reset_system, > }, { > - /* invalidate_*cache_all are gone */ > - .ptr = &efi_runtime_services.set_virtual_address_map, > - .patchto = &efi_unimplemented, > - }, { > /* RTC accessors are gone */ > .ptr = &efi_runtime_services.get_time, > .patchto = &efi_get_time, > @@ -328,7 +324,15 @@ static bool efi_runtime_tobedetached(void *p) > return false; > } > > -static void efi_runtime_detach(ulong offset) > +/** > + * efi_runtime_detach() - Remove any dependency on non-runtime sections > + * > + * This function patches all remaining code to be self-sufficient inside > + * runtime sections. Any calls to non-runtime will be removed after this. > + * > + * @offset: relocaddr for pre-set_v_a_space, offset to VA after > + */ > +__efi_runtime void efi_runtime_detach(ulong offset) > { > int i; > ulong patchoff = offset - (ulong)gd->relocaddr; > @@ -344,6 +348,8 @@ static void efi_runtime_detach(ulong offset) > > /* Update CRC32 */ > efi_update_table_header_crc32(&efi_runtime_services.hdr); > + > + invalidate_icache_all(); > } > > /* Relocate EFI runtime to uboot_reloc_base = offset */ > @@ -430,19 +436,25 @@ void efi_runtime_relocate(ulong offset, struct > efi_mem_desc *map) > * @virtmap: virtual address mapping information > * Return: status code > */ > -static efi_status_t EFIAPI efi_set_virtual_address_map( > +static __efi_runtime efi_status_t EFIAPI efi_set_virtual_address_map( > unsigned long memory_map_size, > unsigned long descriptor_size, > uint32_t descriptor_version, > struct efi_mem_desc *virtmap) > { > + static __efi_runtime_data bool is_patched; > int n = memory_map_size / descriptor_size; > int i; > int rt_code_sections = 0; > > + if (is_patched) > + return EFI_INVALID_PARAMETER; > + > EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size, > descriptor_version, virtmap); > > + is_patched = true; > + > /* > * TODO: > * Further down we are cheating. While really we should implement > @@ -514,8 +526,7 @@ static efi_status_t EFIAPI efi_set_virtual_address_map( > map->physical_start + gd->relocaddr; > > efi_runtime_relocate(new_offset, map); > - /* Once we're virtual, we can no longer handle > - complex callbacks */ > + /* We need to repatch callbacks for their new VA */ > efi_runtime_detach(new_offset); > return EFI_EXIT(EFI_SUCCESS); > } > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot