summaryrefslogtreecommitdiff
path: root/xen/common/efi/boot.c
diff options
context:
space:
mode:
authorLuca Fancellu <luca.fancellu@arm.com>2021-11-05 13:07:28 +0000
committerIan Jackson <iwj@xenproject.org>2021-11-05 15:59:43 +0000
commit9bc9fff04ba077c4a9782f12578362d8947c534b (patch)
treeb790d84b5bc013de1a667b95b4ec057010c40e1f /xen/common/efi/boot.c
parentfaddd16e367530fe4de5480610f69d8ceb6011d8 (diff)
xen/efi: Fix Grub2 boot on arm64
The code introduced by commit a1743fc3a9fe9b68c265c45264dddf214fd9b882 ("arm/efi: Use dom0less configuration when using EFI boot") is introducing a problem to boot Xen using Grub2 on ARM machine using EDK2. Despite UEFI specification, EDK2+Grub2 is returning a NULL DeviceHandle inside the interface given by the LOADED_IMAGE_PROTOCOL service, this handle is used later by efi_bs->HandleProtocol(...) inside get_parent_handle(...) when requesting the SIMPLE_FILE_SYSTEM_PROTOCOL interface, causing Xen to stop the boot because of an EFI_INVALID_PARAMETER error. Before the commit above, the function was never called because the logic was skipping the call when there were multiboot modules in the DT because the filesystem was never used and the bootloader had put in place all the right modules in memory and the addresses in the DT. To fix the problem the old logic is put back in place. Because the handle was given to the efi_check_dt_boot(...), but the revert put the handle out of scope, the signature of the function is changed to use an EFI_LOADED_IMAGE handle and request the EFI_FILE_HANDLE only when needed (module found using xen,uefi-binary). Another problem is found when the UEFI stub tries to check if Dom0 image or DomUs are present. The logic doesn't work when the UEFI stub is not responsible to load any modules, so the efi_check_dt_boot(...) return value is modified to return the number of multiboot module found and not only the number of module loaded by the stub. Taking the occasion to update the comment in handle_module_node(...) to explain why we return success even if xen,uefi-binary is not found. Fixes: a1743fc3a9 ("arm/efi: Use dom0less configuration when using EFI boot") Signed-off-by: Luca Fancellu <luca.fancellu@arm.com> Release-Acked-by: Ian Jackson <iwj@xenproject.org> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
Diffstat (limited to 'xen/common/efi/boot.c')
-rw-r--r--xen/common/efi/boot.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 392ff3ac9b..8fd5e2d078 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -121,6 +121,8 @@ static char *get_value(const struct file *cfg, const char *section,
static char *split_string(char *s);
static CHAR16 *s2w(union string *str);
static char *w2s(const union string *str);
+static EFI_FILE_HANDLE get_parent_handle(EFI_LOADED_IMAGE *loaded_image,
+ CHAR16 **leaf);
static bool read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
struct file *file, const char *options);
static bool read_section(const EFI_LOADED_IMAGE *image, const CHAR16 *name,
@@ -167,7 +169,7 @@ static void __init PrintErr(const CHAR16 *s)
}
#ifndef CONFIG_HAS_DEVICE_TREE
-static int __init efi_check_dt_boot(EFI_FILE_HANDLE dir_handle)
+static int __init efi_check_dt_boot(EFI_LOADED_IMAGE *loaded_image)
{
return 0;
}
@@ -1144,7 +1146,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
const char *option_str;
bool use_cfg_file;
int dt_modules_found;
- EFI_FILE_HANDLE dir_handle;
__set_bit(EFI_BOOT, &efi_flags);
__set_bit(EFI_LOADER, &efi_flags);
@@ -1225,11 +1226,9 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
efi_arch_relocate_image(0);
- /* Get the file system interface. */
- dir_handle = get_parent_handle(loaded_image, &file_name);
-
if ( use_cfg_file )
{
+ EFI_FILE_HANDLE dir_handle;
UINTN depth, cols, rows, size;
size = cols = rows = depth = 0;
@@ -1240,6 +1239,9 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
gop = efi_get_gop();
+ /* Get the file system interface. */
+ dir_handle = get_parent_handle(loaded_image, &file_name);
+
/* Read and parse the config file. */
if ( read_section(loaded_image, L"config", &cfg, NULL) )
PrintStr(L"Using builtin config file\r\n");
@@ -1362,14 +1364,14 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
cfg.addr = 0;
+ dir_handle->Close(dir_handle);
+
if ( gop && !base_video )
gop_mode = efi_find_gop_mode(gop, cols, rows, depth);
}
/* Get the number of boot modules specified on the DT or an error (<0) */
- dt_modules_found = efi_check_dt_boot(dir_handle);
-
- dir_handle->Close(dir_handle);
+ dt_modules_found = efi_check_dt_boot(loaded_image);
if ( dt_modules_found < 0 )
/* efi_check_dt_boot throws some error */