From patchwork Wed Jul 4 15:49:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 10507285 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0034C60325 for ; Wed, 4 Jul 2018 15:49:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E33EE28884 for ; Wed, 4 Jul 2018 15:49:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D747A288BE; Wed, 4 Jul 2018 15:49:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 63E7A28884 for ; Wed, 4 Jul 2018 15:49:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752406AbeGDPt2 (ORCPT ); Wed, 4 Jul 2018 11:49:28 -0400 Received: from mail-ed1-f66.google.com ([209.85.208.66]:43803 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752403AbeGDPt0 (ORCPT ); Wed, 4 Jul 2018 11:49:26 -0400 Received: by mail-ed1-f66.google.com with SMTP id u11-v6so4344148eds.10 for ; Wed, 04 Jul 2018 08:49:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=64T+khMvPYCSc0LkwmPl3whpa/BzeGLlPQrPkqAiBPk=; b=DpbE6zkHu73tGW2xQmaPlobB14zMLuQUA1Rz9f5O1wgO6YWPTSVyxIH59/4I1jH8ab aEtA73GupHB2h1dbZTdMditJ2TBysD03aafz/LKTQgwj8kvKYs3qhAaU/WeImxVItSmg MrhbGXX0kij7pghV/6RibtWdqD4wxGt97EFmY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=64T+khMvPYCSc0LkwmPl3whpa/BzeGLlPQrPkqAiBPk=; b=H4MdG5m9feec4FTEm4pz1iLPTjh4D9jNUHy632iiUqDTx90qDJjNzBUXz6oJ15mmZw 6lfjf7LgngWCmu1HGt9dkODrpvwQhnS63y4wNEVKr0wQtNt/EUXFY9ckQphh1KZgbXfZ qlUb07zBbvJxRbCP8hfMEqlVPHmWW6hOJPoWjJ/yDesgkoTqsD2IauurbprHjple8aUq TU8yGV0SFhNq+86X8LZcj3TKeGlgMppVfXw3qYm+ZydfmlfivBeBtTQN7AM++YYMhsep sAlhtkDMxSpfwbyIkz/aRk9IoWj7EsSnw/5msdsMEo785lH9cQ/zfE4HJNKeIVoKK72I NrUg== X-Gm-Message-State: APt69E1oaFhZsXdbgNetEGROJyROJH5DolFwX32804pa6ByRl0XggMHI g9cneT28gmmR/u5ZuEM+IOonug== X-Google-Smtp-Source: AAOMgpdg+A2WCGNmhr922X2DH36eVWjk05suFa/d7JIRJzKgFWs7y4e2fUUZto58gwG6zuNGvKGUVg== X-Received: by 2002:a50:8266:: with SMTP id 93-v6mr3281588edf.269.1530719365603; Wed, 04 Jul 2018 08:49:25 -0700 (PDT) Received: from ards-mac-mini.arnhem.chello.nl (dhcp-077-251-017-237.chello.nl. [77.251.17.237]) by smtp.gmail.com with ESMTPSA id l61-v6sm1966954edl.96.2018.07.04.08.49.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Jul 2018 08:49:24 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-acpi@vger.kernel.org, leif.lindholm@linaro.org, mark.rutland@arm.com, will.deacon@arm.com, catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Mark Salter , Geoff Levand , Lorenzo Pieralisi , Hanjun Guo , Sudeep Holla , Riku Voipio , James Morse , Ian Campbell Subject: [RFC PATCH 2/2] efi/libstub: taken contents of LinuxExtraArgs UEFI variable into account Date: Wed, 4 Jul 2018 17:49:19 +0200 Message-Id: <20180704154919.18564-3-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180704154919.18564-1-ard.biesheuvel@linaro.org> References: <20180704154919.18564-1-ard.biesheuvel@linaro.org> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In order to allow UEFI platforms to persistently configure Linux kernel options without relying on the contents of the EFI System Partition (ESP) or other block devices, implement support for passing extra kernel command line arguments via the LinuxExtraArgs UEFI variable. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub-helper.c | 51 ++++++++++++++++++++ include/linux/efi.h | 1 + 2 files changed, 52 insertions(+) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 97a2423782af..49a3b03b9f1f 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -35,6 +35,9 @@ static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; static int __section(.data) __nokaslr; static int __section(.data) __quiet; +static const efi_guid_t linux_args_guid = LINUX_EFI_EXTRA_ARGS_GUID; +static const efi_char16_t linux_args_name[] = L"LinuxExtraArgs"; + int __pure nokaslr(void) { return __nokaslr; @@ -786,6 +789,33 @@ static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n) #define MAX_CMDLINE_ADDRESS ULONG_MAX #endif +static u16 *get_extra_args(efi_system_table_t *sys_table_arg, + unsigned long *extra_args_size) +{ + u16 *extra_args; + efi_status_t status; + + *extra_args_size = 0; + status = efi_call_runtime(get_variable, (efi_char16_t *)linux_args_name, + (efi_guid_t *)&linux_args_guid, NULL, + extra_args_size, NULL); + if (status != EFI_BUFFER_TOO_SMALL) + return NULL; + + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + *extra_args_size, (void **)&extra_args); + if (status != EFI_SUCCESS) + return NULL; + + status = efi_call_runtime(get_variable, (efi_char16_t *)linux_args_name, + (efi_guid_t *)&linux_args_guid, NULL, + extra_args_size, extra_args); + if (status != EFI_SUCCESS) + return NULL; + + return extra_args; +} + /* * Convert the unicode UEFI command line to ASCII to pass to kernel. * Size of memory allocated return in *cmd_line_len. @@ -799,9 +829,12 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, unsigned long cmdline_addr = 0; int load_options_chars = image->load_options_size / 2; /* UTF-16 */ const u16 *options = image->load_options; + u16 *extra_args; int cmd_line_bytes = 0; /* UTF-8 bytes */ int options_chars = 0; /* UTF-16 chars */ + int extra_args_chars = 0; /* UTF-16 chars */ efi_status_t status; + unsigned long extra_args_size; u16 zero = 0; if (options) @@ -813,6 +846,19 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, options = &zero; } + extra_args = get_extra_args(sys_table_arg, &extra_args_size); + if (extra_args) { + cmd_line_bytes += 1 + count_utf8_bytes(extra_args, + extra_args_size / 2, + &extra_args_chars); + + pr_efi(sys_table_arg, + "Appending contents of 'LinuxExtraArgs' UEFI variable to kernel command line.\n"); + } else if (extra_args_size > 0) { + pr_efi_err(sys_table_arg, + "Failed to read 'LinuxExtraArgs' UEFI variable\n"); + } + cmd_line_bytes++; /* NUL termination */ status = efi_high_alloc(sys_table_arg, cmd_line_bytes, 0, @@ -821,6 +867,11 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, return NULL; s1 = efi_utf16_to_utf8((u8 *)cmdline_addr, options, options_chars); + if (extra_args) { + *s1++ = ' '; + s1 = efi_utf16_to_utf8(s1, extra_args, extra_args_chars); + efi_call_early(free_pool, extra_args); + } *s1 = '\0'; *cmd_line_len = cmd_line_bytes; diff --git a/include/linux/efi.h b/include/linux/efi.h index 56add823f190..c0902384fa13 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -672,6 +672,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) #define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa) +#define LINUX_EFI_EXTRA_ARGS_GUID EFI_GUID(0x7cae4e6a, 0x08d7, 0x4079, 0x8e, 0xcd, 0x8c, 0x2e, 0xf4, 0x72, 0x30, 0x40) typedef struct { efi_guid_t guid;