From patchwork Sat May 16 15:36:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 206342 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F7B1C433E0 for ; Sat, 16 May 2020 15:37:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 03374207D5 for ; Sat, 16 May 2020 15:37:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OSdcxKwt" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727835AbgEPPh2 (ORCPT ); Sat, 16 May 2020 11:37:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45248 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727082AbgEPPhY (ORCPT ); Sat, 16 May 2020 11:37:24 -0400 Received: from mail-lj1-x244.google.com (mail-lj1-x244.google.com [IPv6:2a00:1450:4864:20::244]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A179DC05BD09; Sat, 16 May 2020 08:37:23 -0700 (PDT) Received: by mail-lj1-x244.google.com with SMTP id f18so5333212lja.13; Sat, 16 May 2020 08:37:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DphE2nru8seGNBj+2DlwSofEvoZcn/+YUXOvNykfsiA=; b=OSdcxKwtbFa/nJZp8XhJ/6pmSfpIYc8T1Inne6GGlCmm7mIehZQrJV5twsuffFobQ+ /RJPhNY8Otq4cwBVIpAgX2bqm7Ktr8KeWszSqKCJQmGVRRkp0C1XSH++gx523QT54J1z ql5lxEdnI+imfKU99vQUg0lS526zJNdELTVaAryHEZ+lWZkXMsLwWMChmJ7im11R+lET DYb69gaPkFH7eUG1MYF8Yc7ars897rgVJ3YpqFr/jPb2CouMyqyITSIpWCNTfzNGd3QN Im7zZiP65IlewRhKqfPqsVPKzwyvw4H9tImZv+Fdro8G2UXNnfrNuG7td+qwqL1NwSKP WMpg== 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:mime-version:content-transfer-encoding; bh=DphE2nru8seGNBj+2DlwSofEvoZcn/+YUXOvNykfsiA=; b=ujsJoWzwiYNj2EtQzj1WN/r4Yz/qtVujiSRyKEjDopzikYCMk7IRwL/Ae/4Zu0wXBz mMmLowKUIndeaerygokZwAYR0xbE343yJLiLZaITc1LFljAy5O0N6Wj+JP7V3LK0W0JL RMVcjLe/E1q4J6TKrhSw5nIqoz3kv+6ROPS+ADp4VmsomovwGyk4Kj5oE8+7OH9R6MDq LJOEwD4rkgNNf+D0CzaFuOOg9b+B4lifFDObcBNxd4+U9macW3ewfdVmaPMxEUhCtLCb md3Ye/91+7yZM2iH1C7sirBmnhTZ/wxqxqMgVchDodUPdUGnb9uwC8yiWn60OLdn6mwS J1EA== X-Gm-Message-State: AOAM5310lbmSzwtx0WWxYR3F7AGcJjpVGaXUeI5/Q9pp36G1H6H/BigX 6/jNTHrN7aCqHd1yk04BQGs= X-Google-Smtp-Source: ABdhPJxDecFzuhnokZ2yW1fqYI8YBMbAJPUIi9NCG0nyg1Sz1rX0AWo+3KZbT1STBMsugq99zXHlow== X-Received: by 2002:a2e:9a41:: with SMTP id k1mr2857432ljj.143.1589643442035; Sat, 16 May 2020 08:37:22 -0700 (PDT) Received: from localhost.localdomain (ppp91-78-208-152.pppoe.mtu-net.ru. [91.78.208.152]) by smtp.gmail.com with ESMTPSA id a12sm2845356ljj.64.2020.05.16.08.37.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 May 2020 08:37:21 -0700 (PDT) From: Dmitry Osipenko To: Jens Axboe , Thierry Reding , Jonathan Hunter , =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= , David Heidelberg , Peter Geis , Stephen Warren , Nicolas Chauvet , Ulf Hansson , Adrian Hunter , Billy Laws , =?utf-8?q?Nils_=C3=96stlund?= , Christoph Hellwig , Ard Biesheuvel , Davidlohr Bueso Cc: linux-tegra@vger.kernel.org, linux-block@vger.kernel.org, Andrey Danin , Gilles Grandou , Ryan Grachek , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, Steve McIntyre , Randy Dunlap , linux-efi Subject: [PATCH v5 4/6] partitions/efi: Support GPT entry lookup at a non-standard location Date: Sat, 16 May 2020 18:36:42 +0300 Message-Id: <20200516153644.13748-5-digetx@gmail.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200516153644.13748-1-digetx@gmail.com> References: <20200516153644.13748-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Most of consumer-grade NVIDIA Tegra devices use a proprietary bootloader that can't be easily replaced because it's locked down using Secure Boot cryptography signing and the crypto keys aren't given to a device owner. These devices usually have eMMC storage that is partitioned using a custom NVIDIA Tegra partition table format. Of course bootloader and other "special things" are stored on the eMMC storage, and thus, the partition format can't be changed. The Tegra partition format has been reverse-engineered, but NVIDIA uses a virtually merged "boot" and "main" eMMC HW partitions in theirs bootloader. This is not supported by Linux kernel and can't be easily implemented. Hence partition table entry isn't accessible by kernel if it's located at the "boot" eMMC partition. Luckily this is a rare case in practice and even if it's the case, likely that the proprietary bootloader will supply kernel with a non-standard gpt_sector= cmdline option. This gpt_sector= argument points at a GPT entry which resides at a non-standard location on the eMMC storage. This patch allows to support the non-standard cmdline option for NVIDIA Tegra devices without bothering any other platforms. The force_gpt_sector parser-state struct member should be set before invoking efi_partition() and it should be unset after the invocation completion. This new parser member instructs GPT parser to look up GPT entry at the given sector if state->force_gpt_sector != 0. This patch is based on the original work done by Colin Cross for the downstream Android kernel. Signed-off-by: Dmitry Osipenko --- block/partitions/check.h | 1 + block/partitions/efi.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/block/partitions/check.h b/block/partitions/check.h index ffa01cc4b0b0..55acf6340e5b 100644 --- a/block/partitions/check.h +++ b/block/partitions/check.h @@ -22,6 +22,7 @@ struct parsed_partitions { int limit; bool access_beyond_eod; char *pp_buf; + sector_t force_gpt_sector; }; typedef struct { diff --git a/block/partitions/efi.c b/block/partitions/efi.c index b64bfdd4326c..3af4660bc11f 100644 --- a/block/partitions/efi.c +++ b/block/partitions/efi.c @@ -621,6 +621,14 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, if (!good_agpt && force_gpt) good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); + /* The force_gpt_sector is used by NVIDIA Tegra partition parser in + * order to convey a non-standard location of the GPT entry for lookup. + * By default force_gpt_sector is set to 0 and has no effect. + */ + if (!good_agpt && force_gpt && state->force_gpt_sector) + good_agpt = is_gpt_valid(state, state->force_gpt_sector, + &agpt, &aptes); + /* The obviously unsuccessful case */ if (!good_pgpt && !good_agpt) goto fail; From patchwork Sat May 16 15:36:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 206341 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48424C433E2 for ; Sat, 16 May 2020 15:37:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 252E820756 for ; Sat, 16 May 2020 15:37:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T2tDKW8K" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727893AbgEPPhm (ORCPT ); Sat, 16 May 2020 11:37:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727822AbgEPPh0 (ORCPT ); Sat, 16 May 2020 11:37:26 -0400 Received: from mail-lf1-x143.google.com (mail-lf1-x143.google.com [IPv6:2a00:1450:4864:20::143]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E757DC05BD0A; Sat, 16 May 2020 08:37:24 -0700 (PDT) Received: by mail-lf1-x143.google.com with SMTP id a4so4301943lfh.12; Sat, 16 May 2020 08:37:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9z0zvsiemKV3eDUGGe0WiR3Rjy6UyeJ7KNmNJhD4f2g=; b=T2tDKW8KzQhm9/Yl2w2W/qMLvHBTdf1NdBiFq7qHXTJL5jxH+gyhbzgv5VrAhAIe4E MrfmE+zW+JIyFsMdL2Lg7F2uySeJZ1vrQqCyLqIJiGSaNQHFPZZOkBncKVc64TC8msQT jG7XmpNEiWcQXHhXIYS1jrvmwsdMX7PEN7u/4HNoqikrvtmtsKnK/B5Jq0gvNu8GEoD+ TfTnSpJzDAARExHV71AGH2W3Eq6T44CBloOABs7cDqqsSBgzzSixdrpmLor623+mBpcI KI469HuebuaAaf7bIbI4E+M7Mv4jx5E863ejvxiFTnKIyOpf5/7lZ3mhDw2AmBnKUXRI /nNA== 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:mime-version:content-transfer-encoding; bh=9z0zvsiemKV3eDUGGe0WiR3Rjy6UyeJ7KNmNJhD4f2g=; b=uMhJ2NuCFjaUqmAy1nOwDZx8ac32rNdhdvQmnOpwuCZwjuIkbFwCeRti2H1XKyHCT0 mS83Cbg53hI2moYKX1F2wwOBQbdVaO0dHi7BVil2vUEMnLQEWrKJHbvltIV//zB7+Nso 9TyDcE/iJe/QdVEPzLc69mgbSUJbE5nA8oVymU2u/jS9R0mafAsvboMS3TG+JWrwDI2+ mINBg2X9NRzKyMKLuyYXJdafBnXWege+VLcvs6bS4E8vaUP4+fE7aBSw4QTJxP+AK2XQ O3C7cAe+IjRr2gIal/bHveYuubgC6vxVD40jx/mqhy3VL33XGsWgEYkElYb9mOOR67iw 4vzw== X-Gm-Message-State: AOAM532K+nLw46CJAufpHWH6eVqPxCHyf62lO2nBoNplNJ52jb6WO5MK O0BMm8kZ/KoDJ15dyJ8JZTQ= X-Google-Smtp-Source: ABdhPJz8ZupxdxfcFg9ynTJ/j6AGwHzFUgWXUMM4giHIPmqk83hbupcd/oDqQJur7bp9gz+biC34vw== X-Received: by 2002:a05:6512:10cd:: with SMTP id k13mr6041250lfg.153.1589643443423; Sat, 16 May 2020 08:37:23 -0700 (PDT) Received: from localhost.localdomain (ppp91-78-208-152.pppoe.mtu-net.ru. [91.78.208.152]) by smtp.gmail.com with ESMTPSA id a12sm2845356ljj.64.2020.05.16.08.37.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 May 2020 08:37:22 -0700 (PDT) From: Dmitry Osipenko To: Jens Axboe , Thierry Reding , Jonathan Hunter , =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= , David Heidelberg , Peter Geis , Stephen Warren , Nicolas Chauvet , Ulf Hansson , Adrian Hunter , Billy Laws , =?utf-8?q?Nils_=C3=96stlund?= , Christoph Hellwig , Ard Biesheuvel , Davidlohr Bueso Cc: linux-tegra@vger.kernel.org, linux-block@vger.kernel.org, Andrey Danin , Gilles Grandou , Ryan Grachek , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, Steve McIntyre , Randy Dunlap , linux-efi Subject: [PATCH v5 5/6] partitions/tegra: Support enforced GPT scanning Date: Sat, 16 May 2020 18:36:43 +0300 Message-Id: <20200516153644.13748-6-digetx@gmail.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200516153644.13748-1-digetx@gmail.com> References: <20200516153644.13748-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Downstream NVIDIA bootloader provides gpt_sector= kernel command line option to the kernel. This option should instruct the GPT partition parser to look at the specified sector for a valid GPT header if the GPT is not found at the beginning or the end of a block device. Support of this feature is needed by Tegra-based devices that have TegraPT and GPT placed in inaccessible by kernel locations. The GPT entry duplicates TegraPT partitions. Secondly, some Tegra-based devices have bootloader that enforces the GPT scanning of the backup/alternative GPT entry by providing "gpt" cmdline option to the kernel, but doesn't provide the "gpt_sector" option. In this case GPT entry resides at a special offset from the end of eMMC storage. It is a common situation for older bootloader versions. The offset is calculated as a total number of eMMC sectors minus number of eMMC boot sectors minus 1. This equation is explicitly defined and used by the downstream Tegra kernels for locating GPT entry. Signed-off-by: Dmitry Osipenko --- block/partitions/check.h | 1 + block/partitions/core.c | 1 + block/partitions/efi.c | 6 +++++ block/partitions/tegra.c | 57 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/block/partitions/check.h b/block/partitions/check.h index 55acf6340e5b..1ce445d1c7f0 100644 --- a/block/partitions/check.h +++ b/block/partitions/check.h @@ -68,5 +68,6 @@ int osf_partition(struct parsed_partitions *state); int sgi_partition(struct parsed_partitions *state); int sun_partition(struct parsed_partitions *state); int sysv68_partition(struct parsed_partitions *state); +int tegra_partition_forced_gpt(struct parsed_partitions *state); int tegra_partition(struct parsed_partitions *state); int ultrix_partition(struct parsed_partitions *state); diff --git a/block/partitions/core.c b/block/partitions/core.c index 0b4720372f07..1931647d9742 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -83,6 +83,7 @@ static int (*check_part[])(struct parsed_partitions *) = { sysv68_partition, #endif #ifdef CONFIG_TEGRA_PARTITION + tegra_partition_forced_gpt, tegra_partition, #endif NULL diff --git a/block/partitions/efi.c b/block/partitions/efi.c index 3af4660bc11f..4eb4496fbb1b 100644 --- a/block/partitions/efi.c +++ b/block/partitions/efi.c @@ -98,6 +98,12 @@ static int force_gpt; static int __init force_gpt_fn(char *str) { + /* This check allows to parse "gpt gpt_sector=" properly since + * "gpt" overlaps with "gpt_sector", see tegra_gpt_sector_fn(). + */ + if (force_gpt) + return 0; + force_gpt = 1; return 1; } diff --git a/block/partitions/tegra.c b/block/partitions/tegra.c index d3a00ade145a..831dedb9a11c 100644 --- a/block/partitions/tegra.c +++ b/block/partitions/tegra.c @@ -565,3 +565,60 @@ int tegra_partition(struct parsed_partitions *state) return ret; } + +/* + * This allows a kernel command line option 'gpt_sector=' to + * enable GPT header lookup at a non-standard location. This option + * is provided to kernel by NVIDIA's proprietary bootloader. + */ +static sector_t tegra_gpt_sector; +static int __init tegra_gpt_sector_fn(char *str) +{ + WARN_ON(kstrtoull(str, 10, &tegra_gpt_sector) < 0); + return 1; +} +__setup("gpt_sector=", tegra_gpt_sector_fn); + +int tegra_partition_forced_gpt(struct parsed_partitions *state) +{ + int ret = 0; + +#ifdef CONFIG_EFI_PARTITION + struct tegra_partition_table_parser ptp = {}; + + if (!soc_is_tegra() || !tegra_boot_sdmmc) + return 0; + + ptp.state = state; + + ptp.boot_offset = tegra_partition_table_emmc_boot_offset(&ptp); + if (ptp.boot_offset < 0) + return 0; + + /* + * Some Tegra devices do not use gpt_sector= kernel command + * line option. In this case these devices usually have a GPT entry + * at the end of the block device and the GPT entry address is + * calculated this way for eMMC: + * + * gpt_sector = ext_csd.sectors_num - ext_csd.boot_sectors_num - 1 + * + * This algorithm is defined and used by NVIDIA in the downstream + * kernel of those devices. + * + * Please note that bootloader supplies the "gpt" cmdline option + * which enforces the GPT scanning, meaning that the scanning will + * be a NO-OP on devices that do not use GPT. + */ + if (tegra_gpt_sector) { + state->force_gpt_sector = tegra_gpt_sector; + } else { + state->force_gpt_sector = get_capacity(state->bdev->bd_disk); + state->force_gpt_sector -= ptp.boot_offset + 1; + } + + ret = efi_partition(state); + state->force_gpt_sector = 0; +#endif + return ret; +}