All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: Etienne Carriere <etienne.carriere@linaro.org>
Cc: Sughosh Ganu <sughosh.ganu@linaro.org>,
	Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	 u-boot@lists.denx.de,
	Patrick Delaunay <patrick.delaunay@foss.st.com>,
	 Patrice Chotard <patrice.chotard@foss.st.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	 Alexander Graf <agraf@csgraf.de>, Bin Meng <bmeng.cn@gmail.com>,
	Peng Fan <peng.fan@nxp.com>,
	AKASHI Takahiro <takahiro.akashi@linaro.org>,
	Jose Marinho <jose.marinho@arm.com>,
	 Grant Likely <Grant.Likely@arm.com>,
	Jason Liu <jason.hui.liu@nxp.com>
Subject: Re: [RESEND RFC PATCH 04/10] FWU: Add metadata access functions for GPT partitioned block devices
Date: Wed, 8 Dec 2021 19:32:16 -0700	[thread overview]
Message-ID: <CAPnjgZ2kGWMEw3ZFdxGRnoKr+4gBKtaCGcnr6DvCgQiXGxhQ1g@mail.gmail.com> (raw)
In-Reply-To: <CAN5uoS8GraJB9r4sF+55mL-kef583jmSPXzEXw1aTiUznnpW1w@mail.gmail.com>

Hi Etienne,

On Wed, 8 Dec 2021 at 07:18, Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> Hi Sughosh, Ilias (and all),
>
> On Thu, 2 Dec 2021 at 08:43, Sughosh Ganu <sughosh.ganu@linaro.org> wrote:
> >
> > hi Ilias,
> >
> > On Wed, 1 Dec 2021 at 17:56, Ilias Apalodimas <ilias.apalodimas@linaro.org>
> > wrote:
> >
> > > Hi Sughosh,
> > >
> > > On Thu, Nov 25, 2021 at 12:42:56PM +0530, Sughosh Ganu wrote:
> > > > In the FWU Multi Bank Update feature, the information about the
> > > > updatable images is stored as part of the metadata, on a separate
> > > > partition. Add functions for reading from and writing to the metadata
> > > > when the updatable images and the metadata are stored on a block
> > > > device which is formated with GPT based partition scheme.
> > > >
> > > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> > > > ---
> > > >  lib/fwu_updates/fwu_metadata_gpt_blk.c | 716 +++++++++++++++++++++++++
> > > >  1 file changed, 716 insertions(+)
> > > >  create mode 100644 lib/fwu_updates/fwu_metadata_gpt_blk.c
> > > >
> > > > +#define SECONDARY_VALID              0x2
> > >
> > >
> > > Change those to BIT(0), BIT(1) etc please
> > >
> >
> > Will change.
> >
> >
> > >
> > > > +
> > > > +#define MDATA_READ           (u8)0x1
> > > > +#define MDATA_WRITE          (u8)0x2
> > > > +
> > > > +#define IMAGE_ACCEPT_SET     (u8)0x1
> > > > +#define IMAGE_ACCEPT_CLEAR   (u8)0x2
> > > > +
> > > > +static int gpt_verify_metadata(struct fwu_metadata *metadata, bool
> > > pri_part)
> > > > +{
> > > > +     u32 calc_crc32;
> > > > +     void *buf;
> > > > +
> > > > +     buf = &metadata->version;
> > > > +     calc_crc32 = crc32(0, buf, sizeof(*metadata) - sizeof(u32));
> > > > +
> > > > +     if (calc_crc32 != metadata->crc32) {
> > > > +             log_err("crc32 check failed for %s metadata partition\n",
> > > > +                     pri_part ? "primary" : "secondary");
> > >
> > > I think we can rid of the 'bool pri_part'.  It's only used for printing and
> > > you can have more that 2 partitions anyway right?
> > >
> >
> > We will have only two partitions for the metadata. But i think looking at
> > it now, it is a bit fuzzy on which is the primary metadata partition and
> > which is the secondary one. Can we instead print the UniquePartitionGUID of
> > the metadata partition instead. That will help in identifying for which
> > metadata copy the verification failed. Let me know your thoughts on this.
> >
> >
> > > > +             return -1;
> > > > +     }
> > > > +
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +static int gpt_get_metadata_partitions(struct blk_desc *desc,
> > >
> > >
> > > Please add a function descriptions (on following functions as well)
> > >
> >
> > I have added the function descriptions in the fwu_metadata.c, where the
> > api's are being defined. Do we need to add the descriptions for the
> > functions in this file as well?
> >
> >
> > >
> > > > +                                    u32 *primary_mpart,
> > > > +                                    u32 *secondary_mpart)
> > >
> > > u16 maybe? This is the number of gpt partitions with metadata right?
> >
> >
> > Okay.
> >
> >
> > >
> > >
> > > > +{
> > > > +     int i, ret;
> > > > +     u32 nparts, mparts;
>
> I think the 2 variables labels are too similar, it's a source of confusion.
> One is a number of entries, the second is a counter. It would be nice
> it's a bit more explicit.
>
> > > > +     gpt_entry *gpt_pte = NULL;
> > > > +     const efi_guid_t fwu_metadata_guid = FWU_METADATA_GUID;
> > > > +
> > > > +     ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1,
> > > > +                                  desc->blksz);
> > > > +
> > > > +     ret = get_gpt_hdr_parts(desc, gpt_head, &gpt_pte);
> > > > +     if (ret < 0) {
> > > > +             log_err("Error getting GPT header and partitions\n");
> > > > +             ret = -EIO;
> > > > +             goto out;
> > > > +     }
> > > > +
> > > > +     nparts = gpt_head->num_partition_entries;
> > > > +     for (i = 0, mparts = 0; i < nparts; i++) {
> > > > +             if (!guidcmp(&fwu_metadata_guid,
> > > > +                          &gpt_pte[i].partition_type_guid)) {
> > > > +                     ++mparts;
> > > > +                     if (!*primary_mpart)
> > > > +                             *primary_mpart = i + 1;
> > > > +                     else
> > > > +                             *secondary_mpart = i + 1;
> > > > +             }
> > > > +     }
> > > > +
> > > > +     if (mparts != 2) {
> > > > +             log_err("Expect two copies of the metadata instead of
> > > %d\n",
> > > > +                     mparts);
> > > > +             ret = -EINVAL;
> > > > +     } else {
> > > > +             ret = 0;
> > > > +     }
> > > > +out:
> > > > +     free(gpt_pte);
> > > > +
> > > > +     return ret;
> > > > +}
> > > > +
> > > > +static int gpt_get_metadata_disk_part(struct blk_desc *desc,
> > > > +                                   struct disk_partition *info,
> > > > +                                   u32 part_num)
> > > > +{
> > > > +     int ret;
> > > > +     char *metadata_guid_str = "8a7a84a0-8387-40f6-ab41-a8b9a5a60d23";
> > > > +
> > > > +     ret = part_get_info(desc, part_num, info);
> > > > +     if (ret < 0) {
> > > > +             log_err("Unable to get the partition info for the metadata
> > > part %d",
> > > > +                     part_num);
> > > > +             return -1;
> > > > +     }
> > > > +
> > > > +     /* Check that it is indeed the metadata partition */
> > > > +     if (!strncmp(info->type_guid, metadata_guid_str, UUID_STR_LEN)) {
> > > > +             /* Found the metadata partition */
> > > > +             return 0;
> > > > +     }
> > > > +
> > > > +     return -1;
> > > > +}
> > > > +
> > > > +static int gpt_read_write_metadata(struct blk_desc *desc,
> > > > +                                struct fwu_metadata *metadata,
> > > > +                                u8 access, u32 part_num)
> > > > +{
> > > > +     int ret;
> > > > +     u32 len, blk_start, blkcnt;
> > > > +     struct disk_partition info;
> > > > +
> > > > +     ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_metadata, mdata, 1,
> > > desc->blksz);
> > > > +
> > > > +     ret = gpt_get_metadata_disk_part(desc, &info, part_num);
> > > > +     if (ret < 0) {
> > > > +             printf("Unable to get the metadata partition\n");
> > > > +             return -ENODEV;
> > > > +     }
> > > > +
> > > > +     len = sizeof(*metadata);
> > > > +     blkcnt = BLOCK_CNT(len, desc);
> > > > +     if (blkcnt > info.size) {
> > > > +             log_err("Block count exceeds metadata partition size\n");
> > > > +             return -ERANGE;
> > > > +     }
> > > > +
> > > > +     blk_start = info.start;
> > > > +     if (access == MDATA_READ) {
> > > > +             if (blk_dread(desc, blk_start, blkcnt, mdata) != blkcnt) {
> > > > +                     log_err("Error reading metadata from the
> > > device\n");
> > > > +                     return -EIO;
> > > > +             }
> > > > +             memcpy(metadata, mdata, sizeof(struct fwu_metadata));
> > > > +     } else {
> > > > +             if (blk_dwrite(desc, blk_start, blkcnt, metadata) !=
> > > blkcnt) {
> > > > +                     log_err("Error writing metadata to the device\n");
> > > > +                     return -EIO;
> > > > +             }
> > > > +     }
> > > > +
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +static int gpt_read_metadata(struct blk_desc *desc,
> > > > +                          struct fwu_metadata *metadata, u32 part_num)
> > > > +{
> > > > +     return gpt_read_write_metadata(desc, metadata, MDATA_READ,
> > > part_num);
> > > > +}
> > > > +
> > > > +static int gpt_write_metadata_partition(struct blk_desc *desc,
> > > > +                                     struct fwu_metadata *metadata,
> > > > +                                     u32 part_num)
> > > > +{
> > > > +     return gpt_read_write_metadata(desc, metadata, MDATA_WRITE,
> > > part_num);
> > > > +}
> > > > +
> > > > +static int gpt_update_metadata(struct fwu_metadata *metadata)
> > > > +{
> > > > +     int ret;
> > > > +     struct blk_desc *desc;
> > > > +     u32 primary_mpart, secondary_mpart;
> > > > +
> > > > +     ret = fwu_plat_get_blk_desc(&desc);
> > > > +     if (ret < 0) {
> > > > +             log_err("Block device not found\n");
> > > > +             return -ENODEV;
> > > > +     }
> > > > +
> > > > +     primary_mpart = secondary_mpart = 0;
> > > > +     ret = gpt_get_metadata_partitions(desc, &primary_mpart,
> > > > +                                       &secondary_mpart);
> > > > +
> > > > +     if (ret < 0) {
> > > > +             log_err("Error getting the metadata partitions\n");
> > > > +             return -ENODEV;
> > > > +     }
> > > > +
> > > > +     /* First write the primary partition*/
> > > > +     ret = gpt_write_metadata_partition(desc, metadata, primary_mpart);
> > > > +     if (ret < 0) {
> > > > +             log_err("Updating primary metadata partition failed\n");
> > > > +             return ret;
> > > > +     }
> > > > +
> > > > +     /* And now the replica */
> > > > +     ret = gpt_write_metadata_partition(desc, metadata,
> > > secondary_mpart);
> > > > +     if (ret < 0) {
> > > > +             log_err("Updating secondary metadata partition failed\n");
> > > > +             return ret;
> > > > +     }
> > >
> > > So shouldn't we do something about this case?  The first partition was
> > > correctly written and the second failed.  Now if the primary GPT somehow
> > > gets corrupted the device is now unusable.
>
> The replica is not there to overcome bitflips of the storage media.
> It's here to allow updates while reliable info a still available in
> the counter part.
> The scheme could be to rely on only 1 instance of the fwu-metadata
> (sorry Simon) image is valid.
> A first load: load 1st instance, crap the second.
> At update: find the crapped one: write it with new data. Upon success
> crapped the alternate one.
> This is a suggestion. There are many ways to handle that.
>
> For sure, the scheme should be well defined so that the boot stage
> that read fwu-data complies with the scheme used to write them.
>
>
>
> > > I assume that depending on what happened to the firmware rollback counter,
> > > we could either try to rewrite this, or revert the first one as well
> > > (assuming rollback counters allow that).
>
> Rollback counters should protect image version management, not
> metadata updates (imho).
>
> > >
> >
> > Okay, although this might be indicative of some underlying hardware issue
> > with the device, else this scenario should not play out.
> >
> >
> > > > +
> > > > +     return 0;
> > > > +}
> > > > +
> > > > +static int gpt_get_valid_metadata(struct fwu_metadata **metadata)
>
> Could be renamed gpt_get_metadata(), we don't expect to get invalid data :)

How about gpt_get_mdata() ?

When I read this I thought it was getting the GPT table...'metadata'
is just too generic.

Regards,
Simon

  reply	other threads:[~2021-12-09  2:33 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-25  7:12 [RESEND RFC PATCH 00/10] FWU: Add support for FWU Multi Bank Update feature Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 01/10] GPT: Add function to get gpt header and partition entries Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 02/10] stm32mp: dfu: Move the ram partitions to the end of the dfu_alt_info variable Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 03/10] FWU: Add metadata structure and functions for accessing metadata Sughosh Ganu
2021-11-26 11:35   ` Ilias Apalodimas
2021-11-29  6:38     ` Sughosh Ganu
2021-11-30 12:57   ` Heinrich Schuchardt
2021-12-01  5:36     ` Sughosh Ganu
2021-12-01  7:50       ` Ilias Apalodimas
2021-12-01  8:31         ` Sughosh Ganu
2021-12-01  7:46     ` Ilias Apalodimas
2021-12-01  6:26   ` Simon Glass
2021-12-01  6:42     ` Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 04/10] FWU: Add metadata access functions for GPT partitioned block devices Sughosh Ganu
2021-12-01 12:26   ` Ilias Apalodimas
2021-12-02  7:43     ` Sughosh Ganu
2021-12-08 14:17       ` Etienne Carriere
2021-12-09  2:32         ` Simon Glass [this message]
2021-12-09  7:37         ` Ilias Apalodimas
2021-12-13  9:29           ` Etienne Carriere
2021-12-01 18:02   ` Simon Glass
2021-12-02  8:05     ` Sughosh Ganu
2021-12-02 13:34       ` Simon Glass
2021-12-03  5:43         ` Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 05/10] FWU: stm32mp1: Add helper functions for accessing metadata Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 06/10] FWU: STM32MP1: Add support to read boot index from backup register Sughosh Ganu
2021-11-25  7:12 ` [RESEND RFC PATCH 07/10] EFI: FMP: Add provision to update image's ImageTypeId in image descriptor Sughosh Ganu
2021-11-26 12:43   ` Heinrich Schuchardt
2021-11-29 11:38     ` Sughosh Ganu
2021-11-25  7:13 ` [RESEND RFC PATCH 08/10] FWU: Add boot time checks as highlighted by the FWU specification Sughosh Ganu
2021-11-25  7:13 ` [RESEND RFC PATCH 09/10] FWU: Add support for FWU Multi Bank Update feature Sughosh Ganu
2021-11-26 12:55   ` Heinrich Schuchardt
2021-11-29 11:44     ` Sughosh Ganu
2021-11-25  7:13 ` [RESEND RFC PATCH 10/10] FWU: cmd: Add a command to read metadata Sughosh Ganu
2021-11-26 12:29 ` [RESEND RFC PATCH 00/10] FWU: Add support for FWU Multi Bank Update feature Heinrich Schuchardt
2021-11-26 12:48   ` Ilias Apalodimas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPnjgZ2kGWMEw3ZFdxGRnoKr+4gBKtaCGcnr6DvCgQiXGxhQ1g@mail.gmail.com \
    --to=sjg@chromium.org \
    --cc=Grant.Likely@arm.com \
    --cc=agraf@csgraf.de \
    --cc=bmeng.cn@gmail.com \
    --cc=etienne.carriere@linaro.org \
    --cc=ilias.apalodimas@linaro.org \
    --cc=jason.hui.liu@nxp.com \
    --cc=jose.marinho@arm.com \
    --cc=patrice.chotard@foss.st.com \
    --cc=patrick.delaunay@foss.st.com \
    --cc=peng.fan@nxp.com \
    --cc=sughosh.ganu@linaro.org \
    --cc=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.