efi/libstub: Unify initrd loading across architectures
authorArvind Sankar <nivedita@alum.mit.edu>
Thu, 30 Apr 2020 18:28:41 +0000 (14:28 -0400)
committerArd Biesheuvel <ardb@kernel.org>
Fri, 1 May 2020 07:40:02 +0000 (09:40 +0200)
Factor out the initrd loading into a common function that can be called
both from the generic efi-stub.c and the x86-specific x86-stub.c.

Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200430182843.2510180-10-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
drivers/firmware/efi/libstub/efi-stub-helper.c
drivers/firmware/efi/libstub/efi-stub.c
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/x86-stub.c

index 1c92ac2..7aac89e 100644 (file)
@@ -331,6 +331,7 @@ static const struct {
  *             %EFI_OUT_OF_RESOURCES if memory allocation failed
  *             %EFI_LOAD_ERROR in all other cases
  */
+static
 efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
                                      unsigned long *load_size,
                                      unsigned long max)
@@ -343,9 +344,6 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
        efi_handle_t handle;
        efi_status_t status;
 
-       if (!load_addr || !load_size)
-               return EFI_INVALID_PARAMETER;
-
        dp = (efi_device_path_protocol_t *)&initrd_dev_path;
        status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
        if (status != EFI_SUCCESS)
@@ -375,3 +373,45 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
        *load_size = initrd_size;
        return EFI_SUCCESS;
 }
+
+static
+efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
+                                    unsigned long *load_addr,
+                                    unsigned long *load_size,
+                                    unsigned long soft_limit,
+                                    unsigned long hard_limit)
+{
+       if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
+           (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
+               *load_addr = *load_size = 0;
+               return EFI_SUCCESS;
+       }
+
+       return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
+                                   soft_limit, hard_limit,
+                                   load_addr, load_size);
+}
+
+efi_status_t efi_load_initrd(efi_loaded_image_t *image,
+                            unsigned long *load_addr,
+                            unsigned long *load_size,
+                            unsigned long soft_limit,
+                            unsigned long hard_limit)
+{
+       efi_status_t status;
+
+       if (!load_addr || !load_size)
+               return EFI_INVALID_PARAMETER;
+
+       status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
+       if (status == EFI_SUCCESS) {
+               efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
+       } else if (status == EFI_NOT_FOUND) {
+               status = efi_load_initrd_cmdline(image, load_addr, load_size,
+                                                soft_limit, hard_limit);
+               if (status == EFI_SUCCESS && *load_size > 0)
+                       efi_info("Loaded initrd from command line option\n");
+       }
+
+       return status;
+}
index cb02e8b..63541c2 100644 (file)
@@ -265,16 +265,8 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
 
        if (!efi_noinitrd) {
                max_addr = efi_get_max_initrd_addr(dram_base, image_addr);
-               status = efi_load_initrd_dev_path(&initrd_addr, &initrd_size,
-                                                 max_addr);
-               if (status == EFI_SUCCESS) {
-                       efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
-               } else if (status == EFI_NOT_FOUND) {
-                       status = efi_load_initrd(image, &initrd_addr, &initrd_size,
-                                                ULONG_MAX, max_addr);
-                       if (status == EFI_SUCCESS && initrd_size > 0)
-                               efi_info("Loaded initrd from command line option\n");
-               }
+               status = efi_load_initrd(image, &initrd_addr, &initrd_size,
+                                        ULONG_MAX, max_addr);
                if (status != EFI_SUCCESS)
                        efi_err("Failed to load initrd!\n");
        }
index 8c905a1..874233c 100644 (file)
@@ -677,21 +677,10 @@ static inline efi_status_t efi_load_dtb(efi_loaded_image_t *image,
                                    ULONG_MAX, ULONG_MAX, load_addr, load_size);
 }
 
-static inline efi_status_t efi_load_initrd(efi_loaded_image_t *image,
-                                          unsigned long *load_addr,
-                                          unsigned long *load_size,
-                                          unsigned long soft_limit,
-                                          unsigned long hard_limit)
-{
-       if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER))
-               return EFI_SUCCESS;
-
-       return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
-                                   soft_limit, hard_limit, load_addr, load_size);
-}
-
-efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
-                                     unsigned long *load_size,
-                                     unsigned long max);
+efi_status_t efi_load_initrd(efi_loaded_image_t *image,
+                            unsigned long *load_addr,
+                            unsigned long *load_size,
+                            unsigned long soft_limit,
+                            unsigned long hard_limit);
 
 #endif
index defeb60..f1a1345 100644 (file)
@@ -755,17 +755,8 @@ unsigned long efi_main(efi_handle_t handle,
        if (!efi_noinitrd) {
                unsigned long addr, size;
 
-               status = efi_load_initrd_dev_path(&addr, &size, ULONG_MAX);
-               if (status == EFI_NOT_FOUND) {
-                       if (efi_is_native() && image != NULL) {
-                               status = efi_load_initrd(image, &addr, &size,
-                                                        hdr->initrd_addr_max,
-                                                        ULONG_MAX);
-                       } else {
-                               addr = size = 0;
-                               status = EFI_SUCCESS;
-                       }
-               }
+               status = efi_load_initrd(image, &addr, &size,
+                                        hdr->initrd_addr_max, ULONG_MAX);
 
                if (status != EFI_SUCCESS) {
                        efi_err("Failed to load initrd!\n");