Use cmdline building function in EFI.

EFI cannot use pr_err() and doesn't have a .init.data section,
so use the __cmdline_build() internal function and provides
both a source and a destination.

Remove the handling of too long command lines as it is handled
by the generic CMDLINE.

Signed-off-by: Christophe Leroy <christophe.le...@csgroup.eu>
---
v4: New
---
 .../firmware/efi/libstub/efi-stub-helper.c    | 35 ++++++++++---------
 drivers/firmware/efi/libstub/efi-stub.c       | 23 +++---------
 drivers/firmware/efi/libstub/efistub.h        |  2 +-
 drivers/firmware/efi/libstub/x86-stub.c       | 18 +++-------
 4 files changed, 29 insertions(+), 49 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c 
b/drivers/firmware/efi/libstub/efi-stub-helper.c
index aa8da0a49829..9f60d471d650 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -13,6 +13,7 @@
 #include <linux/efi.h>
 #include <linux/kernel.h>
 #include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
+#include <linux/cmdline.h>
 #include <asm/efi.h>
 #include <asm/setup.h>
 
@@ -339,13 +340,13 @@ void efi_apply_loadoptions_quirk(const void 
**load_options, int *load_options_si
  * Size of memory allocated return in *cmd_line_len.
  * Returns NULL on error.
  */
-char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
+char *efi_convert_cmdline(efi_loaded_image_t *image)
 {
        const u16 *s2;
-       unsigned long cmdline_addr = 0;
+       unsigned long cmdline_addr = 0, options_addr = 0;
        int options_chars = efi_table_attr(image, load_options_size);
        const u16 *options = efi_table_attr(image, load_options);
-       int options_bytes = 0, safe_options_bytes = 0;  /* UTF-8 bytes */
+       int options_bytes = 0;  /* UTF-8 bytes */
        bool in_quote = false;
        efi_status_t status;
 
@@ -354,16 +355,12 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int 
*cmd_line_len)
 
        if (options) {
                s2 = options;
-               while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
+               while (options_chars--) {
                        u16 c = *s2++;
 
                        if (c < 0x80) {
                                if (c == L'\0' || c == L'\n')
                                        break;
-                               if (c == L'"')
-                                       in_quote = !in_quote;
-                               else if (!in_quote && isspace((char)c))
-                                       safe_options_bytes = options_bytes;
 
                                options_bytes++;
                                continue;
@@ -395,24 +392,30 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int 
*cmd_line_len)
                                }
                        }
                }
-               if (options_bytes >= COMMAND_LINE_SIZE) {
-                       options_bytes = safe_options_bytes;
-                       efi_err("Command line is too long: truncated to %d 
bytes\n",
-                               options_bytes);
-               }
        }
 
        options_bytes++;        /* NUL termination */
 
        status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes,
-                            (void **)&cmdline_addr);
+                            (void **)&options_addr);
        if (status != EFI_SUCCESS)
                return NULL;
 
-       snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
+       snprintf((char *)options_addr, options_bytes, "%.*ls",
                 options_bytes - 1, options);
 
-       *cmd_line_len = options_bytes;
+       status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, COMMAND_LINE_SIZE,
+                            (void **)&cmdline_addr);
+       if (status != EFI_SUCCESS) {
+               efi_bs_call(free_pool, (void *)options_addr);
+               return NULL;
+       }
+
+       if (!__cmdline_build((char *)cmdline_addr, (char *)options_addr))
+               efi_err("Command line is too long\n");
+
+       efi_bs_call(free_pool, (void *)cmdline_addr);
+
        return (char *)cmdline_addr;
 }
 
diff --git a/drivers/firmware/efi/libstub/efi-stub.c 
b/drivers/firmware/efi/libstub/efi-stub.c
index 26e69788f27a..b79ee76f2e95 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -127,7 +127,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
        unsigned long fdt_addr = 0;  /* Original DTB */
        unsigned long fdt_size = 0;
        char *cmdline_ptr = NULL;
-       int cmdline_size = 0;
        efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
        unsigned long reserve_addr = 0;
        unsigned long reserve_size = 0;
@@ -165,29 +164,17 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
         * protocol. We are going to copy the command line into the
         * device tree, so this can be allocated anywhere.
         */
-       cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
+       cmdline_ptr = efi_convert_cmdline(image);
        if (!cmdline_ptr) {
                efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
                status = EFI_OUT_OF_RESOURCES;
                goto fail;
        }
 
-       if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
-           IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
-           cmdline_size == 0) {
-               status = efi_parse_options(CONFIG_CMDLINE);
-               if (status != EFI_SUCCESS) {
-                       efi_err("Failed to parse options\n");
-                       goto fail_free_cmdline;
-               }
-       }
-
-       if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) {
-               status = efi_parse_options(cmdline_ptr);
-               if (status != EFI_SUCCESS) {
-                       efi_err("Failed to parse options\n");
-                       goto fail_free_cmdline;
-               }
+       status = efi_parse_options(cmdline_ptr);
+       if (status != EFI_SUCCESS) {
+               efi_err("Failed to parse options\n");
+               goto fail_free_cmdline;
        }
 
        efi_info("Booting Linux Kernel...\n");
diff --git a/drivers/firmware/efi/libstub/efistub.h 
b/drivers/firmware/efi/libstub/efistub.h
index cde0a2ef507d..2f872c48b20b 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -780,7 +780,7 @@ void efi_free(unsigned long size, unsigned long addr);
 
 void efi_apply_loadoptions_quirk(const void **load_options, int 
*load_options_size);
 
-char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len);
+char *efi_convert_cmdline(efi_loaded_image_t *image);
 
 efi_status_t efi_get_memory_map(struct efi_boot_memmap *map);
 
diff --git a/drivers/firmware/efi/libstub/x86-stub.c 
b/drivers/firmware/efi/libstub/x86-stub.c
index 28659276b6ba..0f6a33149ef7 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -359,7 +359,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
        struct setup_header *hdr;
        void *image_base;
        efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
-       int options_size = 0;
        efi_status_t status;
        char *cmdline_ptr;
 
@@ -404,7 +403,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
        hdr->type_of_loader = 0x21;
 
        /* Convert unicode cmdline to ascii */
-       cmdline_ptr = efi_convert_cmdline(image, &options_size);
+       cmdline_ptr = efi_convert_cmdline(image);
        if (!cmdline_ptr)
                goto fail;
 
@@ -674,6 +673,8 @@ unsigned long efi_main(efi_handle_t handle,
        unsigned long buffer_start, buffer_end;
        struct setup_header *hdr = &boot_params->hdr;
        efi_status_t status;
+       unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr |
+                                      ((u64)boot_params->ext_cmd_line_ptr << 
32));
 
        efi_system_table = sys_table_arg;
 
@@ -735,22 +736,11 @@ unsigned long efi_main(efi_handle_t handle,
                image_offset = 0;
        }
 
-#ifdef CONFIG_CMDLINE_BOOL
-       status = efi_parse_options(CONFIG_CMDLINE);
+       status = efi_parse_options((char *)cmdline_paddr);
        if (status != EFI_SUCCESS) {
                efi_err("Failed to parse options\n");
                goto fail;
        }
-#endif
-       if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
-               unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr |
-                                              
((u64)boot_params->ext_cmd_line_ptr << 32));
-               status = efi_parse_options((char *)cmdline_paddr);
-               if (status != EFI_SUCCESS) {
-                       efi_err("Failed to parse options\n");
-                       goto fail;
-               }
-       }
 
        /*
         * At this point, an initrd may already have been loaded by the
-- 
2.25.0

Reply via email to