[U-Boot] [PATCH] efi_loader: allow efi_loader code to call EFI interfaces

Alexander Graf
2017-07-25T08:10:16Z

On 25.07.17 01:47, Rob Clark wrote:
> To implement efi_load_image() for the case of loading an image from a
> device path rather than image already loaded into source_buffer, it is
> convenient to be able to re-use simple-file-system and efi-file
> interfaces. But these are already using EFI_ENTER()/EFI_EXIT(). Allow
> entry into EFI interfaces to be recursive, since this greatly simplifies
> things.
>
> (And hypothetically this would be needed anyways to allow grub to call
> into interfaces installed by something outside of grub.)
>
> Signed-off-by: Rob Clark <robdclark@gmail.com>

So there are 2 ways to do this:

1) Keep a refcount, only transition when passing the 0 level
2) Explicitly split functions with ENTRY/EXIT from their core functions

So far we used approach 2, splitting functions that are used by both
internal and external code into _ext (for externally called) and normal
functions. You can see this pattern quite a few times throughout efi_loader.

I definitely did try the refcount approach back when I decided for
approach 2 and it failed on me in some case, but I can't remember where.

Either way, we should definitely be consistent. Either we always use
refcounting or we shouldn't bother with it. So if you can make a version
work where all _ext variants disappear and we're magically reentrant,
I'll be happy to take that. I'm fairly sure it'll break somewhere though :).

Alex

> ---
> lib/efi_loader/efi_boottime.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index 8735b1f418..a113124708 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -47,6 +47,7 @@ static struct efi_configuration_table __efi_runtime_data efi_conf_table[2];
> * EFI callback entry/exit.
> */
> static volatile void *efi_gd, *app_gd;
> +static int entry_level = 0;
> #endif
>
> /* Called from do_bootefi_exec() */
> @@ -61,6 +62,8 @@ void efi_save_gd(void)
> void efi_restore_gd(void)
> {
> #ifdef CONFIG_ARM
> + if (entry_level++)
> + return;
> /* Only restore if we're already in EFI context */
> if (!efi_gd)
> return;
> @@ -75,6 +78,8 @@ void efi_restore_gd(void)
> efi_status_t efi_exit_func(efi_status_t ret)
> {
> #ifdef CONFIG_ARM
> + if (--entry_level)
> + return ret;
> gd = app_gd;
> #endif
>
>