From patchwork Mon Jul 4 05:16:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 587098 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1ec:0:0:0:0 with SMTP id 12csp499471map; Sun, 3 Jul 2022 22:19:03 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t4mw6n0lAPTlym4wSGF1+8sY3AV3VUo6v6Gel1XvIbTMZqdgB9ZZenvl9JNWddBxe3bbdo X-Received: by 2002:a05:6512:2255:b0:47f:6591:354b with SMTP id i21-20020a056512225500b0047f6591354bmr18802897lfu.191.1656911943042; Sun, 03 Jul 2022 22:19:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656911943; cv=none; d=google.com; s=arc-20160816; b=TeyAIQq++C7oUY9dhTjFBL5SB/kH6Gc1FicfGKb2SGfWyhQzTfWjlWYi9TC1zq8dhj PmXrHzmzN9hwn1EieRnwAXgmK7MVxrJygjxzJA8ujrToOP0THGG4mpLuJpB1OZqWxuNu FwCGZjIXYcU31GSTVb/er9XUWFluI2m+cAoa08O3acTNkkLOseahw1jjB33zTiE7lMD+ 7573V31qeMfiLMnOUFdndMcE3pqdCVg5R+xlooHrPvnNJParXwXgsyvJ5sMWT5FUH19t 3mnQ0tVPqeOR+wJs2smc4bdGuZv2/YD/tRVBEdtf9M1egTUbY8TyyvgsWH1tD6VwWAyz zxug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=mvwdaY80xsskleBO4lt/2Jk3W/QGsJc5d58ngov/Ohw=; b=jgnPkFcVtd8PeAqPRt2cb2HTtey7cdo1HRqKrzCPzMTk/t3Zr2OqATqlotzAf8rt0I TpGBrxYcCF5P9N0i86j7FvhcRlFG9Siv0sL7kBwwV4C38874pOmZdLnQ9GNbnWXnQDOu pD9QtJ31ZWXFZUur3PgFfTePY1837ZRtJ/W9Aws/Z++5Bvz7yqfrMvti3cUF8MY4CIwL DwkPHzmNxrDdNx6u9fUKkZnQ13CfUsS5gDVfn1gDoPhopd/S0CBb4LBJ4mwhEjNJaS2l Uatm2ghUBj+ObrBGevGw4UeWpJ8lDK6NqyaNcQEYiA3ngj8EmdzPrP1Feo7S/Y0letTC oh4Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id r8-20020ac25c08000000b0047f8528692esi25437712lfp.64.2022.07.03.22.19.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Jul 2022 22:19:03 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3F9FE8452C; Mon, 4 Jul 2022 07:18:10 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id A6DB68452B; Mon, 4 Jul 2022 07:18:08 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 1BA728452D for ; Mon, 4 Jul 2022 07:18:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B16042B; Sun, 3 Jul 2022 22:18:03 -0700 (PDT) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BB87E3F66F; Sun, 3 Jul 2022 22:17:59 -0700 (PDT) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Patrick Delaunay , Patrice Chotard , Simon Glass , Bin Meng , Tom Rini , Etienne Carriere , Michal Simek , Jassi Brar , Sughosh Ganu Subject: [PATCH v6 08/13] FWU: Add boot time checks as highlighted by the FWU specification Date: Mon, 4 Jul 2022 10:46:53 +0530 Message-Id: <20220704051658.1085442-9-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220704051658.1085442-1-sughosh.ganu@linaro.org> References: <20220704051658.1085442-1-sughosh.ganu@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean The FWU Multi Bank Update specification requires the Update Agent to carry out certain checks at the time of platform boot. The Update Agent is the component which is responsible for updating the firmware components and maintaining and keeping the metadata in sync. The spec requires that the Update Agent perform the following checks at the time of boot * Sanity check of both the metadata copies maintained by the platform. * Get the boot index passed to U-Boot by the prior stage bootloader and use this value for metadata bookkeeping. * Check if the system is booting in Trial State. If the system boots in the Trial State for more than a specified number of boot counts, change the Active Bank to be booting the platform from. Add these checks in the board initialisation sequence, invoked after relocation. Signed-off-by: Sughosh Ganu --- Changes since V5: * Use u"TrialStateCtr" for the EFI variable name as suggested by Patrick * Dropped the call to uclass_get_device() in fwu_boottime_checks() as suggested by Patrick * Pass NULL instead of a pointer to trial_state_ctr variable when deleting the variable as suggested by Etienne common/board_r.c | 5 ++ include/fwu.h | 3 + lib/fwu_updates/fwu.c | 165 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 lib/fwu_updates/fwu.c diff --git a/common/board_r.c b/common/board_r.c index 6f4aca2077..33a600715d 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -797,6 +798,10 @@ static init_fnc_t init_sequence_r[] = { #if defined(CONFIG_PRAM) initr_mem, #endif + +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE + fwu_boottime_checks, +#endif run_main_loop, }; diff --git a/include/fwu.h b/include/fwu.h index edb28c9659..b374fd1179 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -37,6 +37,9 @@ struct fwu_mdata_ops { EFI_GUID(0x8a7a84a0, 0x8387, 0x40f6, 0xab, 0x41, \ 0xa8, 0xb9, 0xa5, 0xa6, 0x0d, 0x23) +u8 fwu_update_checks_pass(void); +int fwu_boottime_checks(void); + int fwu_get_mdata(struct fwu_mdata **mdata); int fwu_update_mdata(struct fwu_mdata *mdata); int fwu_get_active_index(u32 *active_idx); diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c new file mode 100644 index 0000000000..10a0522333 --- /dev/null +++ b/lib/fwu_updates/fwu.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static u8 trial_state; +static u8 boottime_check; + +static int fwu_trial_state_check(void) +{ + int ret, i; + efi_status_t status; + efi_uintn_t var_size; + u16 trial_state_ctr; + u32 nimages, active_bank, var_attributes, active_idx; + struct fwu_mdata *mdata = NULL; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + ret = fwu_get_mdata(&mdata); + if (ret) + return ret; + + ret = 0; + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + active_bank = mdata->active_index; + img_entry = &mdata->img_entry[0]; + for (i = 0; i < nimages; i++) { + img_bank_info = &img_entry[i].img_bank_info[active_bank]; + if (!img_bank_info->accepted) { + trial_state = 1; + break; + } + } + + if (trial_state) { + var_size = (efi_uintn_t)sizeof(trial_state_ctr); + log_info("System booting in Trial State\n"); + var_attributes = EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS; + status = efi_get_variable_int(u"TrialStateCtr", + &efi_global_variable_guid, + &var_attributes, + &var_size, &trial_state_ctr, + NULL); + if (status != EFI_SUCCESS) { + log_err("Unable to read TrialStateCtr variable\n"); + ret = -1; + goto out; + } + + ++trial_state_ctr; + if (trial_state_ctr > CONFIG_FWU_TRIAL_STATE_CNT) { + log_info("Trial State count exceeded. Revert back to previous_active_index\n"); + active_idx = mdata->active_index; + ret = fwu_revert_boot_index(); + if (ret) { + log_err("Unable to revert active_index\n"); + goto out; + } + + /* Delete the TrialStateCtr variable */ + status = efi_set_variable_int(u"TrialStateCtr", + &efi_global_variable_guid, + var_attributes, + 0, NULL, false); + if (status != EFI_SUCCESS) { + log_err("Unable to delete TrialStateCtr variable\n"); + ret = -1; + goto out; + } + } else { + status = efi_set_variable_int(u"TrialStateCtr", + &efi_global_variable_guid, + var_attributes, + var_size, + &trial_state_ctr, false); + if (status != EFI_SUCCESS) { + log_err("Unable to increment TrialStateCtr variable\n"); + ret = -1; + goto out; + } + } + } else { + /* Delete the variable */ + status = efi_set_variable_int(u"TrialStateCtr", + &efi_global_variable_guid, + 0, 0, NULL, NULL); + if (status != EFI_SUCCESS && status != EFI_NOT_FOUND) { + ret = -1; + log_err("Unable to delete TrialStateCtr variable\n"); + } + } + +out: + free(mdata); + return ret; +} + +u8 fwu_update_checks_pass(void) +{ + return !trial_state && boottime_check; +} + +int fwu_boottime_checks(void) +{ + int ret; + u32 boot_idx, active_idx; + + ret = fwu_mdata_check(); + if (ret) { + return 0; + } + + /* + * Get the Boot Index, i.e. the bank from + * which the platform has booted. This value + * gets passed from the ealier stage bootloader + * which booted u-boot, e.g. tf-a. If the + * boot index is not the same as the + * active_index read from the FWU metadata, + * update the active_index. + */ + fwu_plat_get_bootidx(&boot_idx); + if (boot_idx >= CONFIG_FWU_NUM_BANKS) { + log_err("Received incorrect value of boot_index\n"); + return 0; + } + + ret = fwu_get_active_index(&active_idx); + if (ret) { + log_err("Unable to read active_index\n"); + return 0; + } + + if (boot_idx != active_idx) { + log_info("Boot idx %u is not matching active idx %u, changing active_idx\n", + boot_idx, active_idx); + ret = fwu_update_active_index(boot_idx); + if (!ret) + boottime_check = 1; + + return 0; + } + + if (efi_init_obj_list() != EFI_SUCCESS) + return 0; + + ret = fwu_trial_state_check(); + if (!ret) + boottime_check = 1; + + return 0; +}