From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) by mx.groups.io with SMTP id smtpd.web12.1571.1614801756017169779 for ; Wed, 03 Mar 2021 12:02:36 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=nEKouLTh; spf=pass (domain: linaro.org, ip: 209.85.218.54, mailfrom: ilias.apalodimas@linaro.org) Received: by mail-ej1-f54.google.com with SMTP id r17so44615571ejy.13 for ; Wed, 03 Mar 2021 12:02:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=1Hdh3t8AXUmrb/oUehp8Wz/6Tf1RiC3zV0J5b/KuWM8=; b=nEKouLThUJ5v2tiTZ3Y1AF2Nlvi2gd+cbbBRgWYP82hFL84LL8iBRBxOQ/pb3vAatY zJENqVRQolLdFpHpEsq9l0SC5kz6ogtyeu2ubRS7cGNwCjsytkIPE4Bcdt2Y5CFMtJyi wXMvOsbYdpwjYhUqCbudxqQgn0KC0P6Davil/RJ3bVZdmpZI1qSLwqBbfABnuP5A82dN LZ5bvqpmhoOSJSy1HWaOQYAk2qIWs28e1Q1PEsTU/JVvP5FSv5+ZSIFXsyiZNZz/AVbl a0zDZLvBcSPhd+74rUkKh9LxB0CpnLlSuM15/I/WMk7bAvPePV+GCqof15/+SxCrkHQ6 u/mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=1Hdh3t8AXUmrb/oUehp8Wz/6Tf1RiC3zV0J5b/KuWM8=; b=NkqH2PBg6T9r+DugTY+4sheRSVnAmG6NX10G0grYsv2o9J/zSztdX7MuSJDRmPyfgQ /zLYEQx3fW4YAoS+3xJd99C3YHzDfkZUTZwRpKwzWRLv6EiTSXe5MuYZkFUgNLJuFKyu JqeoBqk2T3GoQeTxUOYXbHP+qBLr2rzkZsI7pG04ROZzka/M6mWffEZgvN0oNOYFStIq ssC/ByaiFa8E5vmHSHVaMBg1XcuJiOExFOIxZKMhWRzmYTljagiUQFIYl1kCDTlEJmg4 YCkZIZfHMEJt6/GFx9PRZgJKe8HHWSrY/oX0+F9f9J4zYsDH5K0KI1q8ZBz6RdMCnj5o Qz/w== X-Gm-Message-State: AOAM531qR8rcOZlwgm16xKLeNKOPDpUhstQLH4Is6wE6yRylZjuEGiPG mfTnljsaovLgW9/bc9HYV/jw9w== X-Google-Smtp-Source: ABdhPJzrje84CTem7XbNT8l0JWEuCr8XUoobElTWw9/YulcwPpBKlsaro43De/aCheHrlqRQe5Y7PQ== X-Received: by 2002:a17:907:9626:: with SMTP id gb38mr459240ejc.301.1614801754421; Wed, 03 Mar 2021 12:02:34 -0800 (PST) Return-Path: Received: from apalos.home (ppp-94-64-113-158.home.otenet.gr. [94.64.113.158]) by smtp.gmail.com with ESMTPSA id x25sm22443039edv.65.2021.03.03.12.02.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Mar 2021 12:02:33 -0800 (PST) Date: Wed, 3 Mar 2021 22:02:31 +0200 From: "Ilias Apalodimas" To: Pierre Cc: devel@edk2.groups.io, Sami.Mujawar@arm.com Subject: Re: [edk2-devel] [PATCH 1/2 v5] Drivers/OpTeeRpmb: Add an OP-TEE backed RPMB driver Message-ID: References: <20210212173459.508205-1-ilias.apalodimas@linaro.org> <20210212173459.508205-2-ilias.apalodimas@linaro.org> <51d77291-571b-1635-caa4-590f66c75b56@arm.com> MIME-Version: 1.0 In-Reply-To: <51d77291-571b-1635-caa4-590f66c75b56@arm.com> Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi Pierre, On Wed, Mar 03, 2021 at 10:20:17AM +0000, Pierre wrote: > Hello Ilias, > > My review is mostly about coding style, but I would have some (inlined) > remarks about your patch, > > Regards, > > Pierre > > On 3/2/21 3:35 PM, Pierre Gondois wrote: > > > > > [...] > > +  offer that from an RPMB, the driver allocates memory on init and > > passes that > > > > +  on the upper layers. Since the memory is dynamically allocated and we > > can't set the > > > > +  PCD is StMM context, we need to patch it correctly on each access > I think: is -> in Ok > > > > + > > > > +  @retval EFI_SUCCESS Protocol was found and PCDs patched up > > > > + > > > > + **/ > > I think there should not be a space here. Ok > > > > > +EFI_STATUS > > > > +EFIAPI > > > > +FixPcdMemory ( > > [...] > > + > > > > +  // Patch PCDs with the the correct values > I think it s > 'the the' -> the Yea > > > > +  PatchPcdSet64 (PcdFlashNvStorageVariableBase64, > > Instance->MemBaseAddress); [...] > > +  @retval           EFI_OUT_OF_RESOURCES op-tee out of memory > > > > +**/ > > > > +STATIC > > > > +EFI_STATUS > > > > +ReadWriteRpmb ( > > > > +  UINTN  SvcAct, > > > > +  UINTN  Addr, > > > > +  UINTN  NumBytes, > > > > +  UINTN  Offset > > > > +  ) > > I think the parameters should have IN/OUT indications, and the function > header aswell (cf https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/6_documenting_software/62_comments#6-2-1-only-use-c-style-comments-on-the-same-line-as-pre-processor-directives-and-in-doxygen-style-file-and-function-header-comment-blocks). > There are other functions with missing IN/OUT parameters. Sure, (did you c/p the wrong link?) > > > > > +{ > > [...] > > +OpTeeRpmbFvbSetAttributes ( > > > > +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > > > > +  IN OUT    EFI_FVB_ATTRIBUTES_2 *Attributes > Parameters should be aligned. (I think this is valid at other places, like > for OpTeeRpmbFvbGetPhysicalAddress()) Ok > > > > +  ) [...] > > +  The GetBlockSize() function retrieves the size of the requested > > > > +  block. It also returns the number of additional blocks with > > > > +  the identical size. The GetBlockSize() function is used to > > > > +  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). > > > > + > > > > + > > > > +  @param This           Indicates the > > EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL instance. > > > > + > > > > +  @param Lba            Indicates the block for which to return the size. > > > > + > > > > +  @param BlockSize      Pointer to a caller-allocated UINTN in which > > > > +                        the size of the block is returned. > > > > + > > > > +  @param NumberOfBlocks Pointer to a caller-allocated UINTN in > > > > +                        which the number of consecutive blocks, > > > > +                        starting with Lba, is returned. All > > > > +                        blocks in this range have a size of > > > > +                        BlockSize. > > > > + > > > > + > > > > +  @retval EFI_SUCCESS             The firmware volume base address was > > returned. > > > > + > > > > +  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range. > > > > + > > > > +**/ > > > > +STATIC > > > > +EFI_STATUS > > > > +OpTeeRpmbFvbGetBlockSize ( > > > > +  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > > > > +  IN        EFI_LBA                            Lba, > > > > +  OUT       UINTN *BlockSize, > > > > +  OUT       UINTN *NumberOfBlocks > > > > +  ) > > > > +{ > > > > +  MEM_INSTANCE *Instance; > > > > + > > > > +  Instance = INSTANCE_FROM_FVB_THIS (This); > > > > +  if (Lba > Instance->NBlocks) { > > > > +    return EFI_INVALID_PARAMETER; > > > > +  } > > > > + > > > > +  *NumberOfBlocks = Instance->NBlocks - (UINTN)Lba; > > > > +  *BlockSize = Instance->BlockSize; > > > > + > > > > +  return EFI_SUCCESS; > > > > +} > > > > + > > > > +/** > > > > +  Reads the specified number of bytes into a buffer from the specified > > block. > > > > + > > > > +  The Read() function reads the requested number of bytes from the > > > > +  requested block and stores them in the provided buffer. > > > > +  Implementations should be mindful that the firmware volume > > > > +  might be in the ReadDisabled state. If it is in this state, > > > > +  the Read() function must return the status code > > > > +  EFI_ACCESS_DENIED without modifying the contents of the > > > > +  buffer. The Read() function must also prevent spanning block > > > > +  boundaries. If a read is requested that would span a block > > > > +  boundary, the read must read up to the boundary but not > > > > +  beyond. The output parameter NumBytes must be set to correctly > > > > +  indicate the number of bytes actually read. The caller must be > > > > +  aware that a read may be partially completed. > > > > + > > > > +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL > > instance. > > > > + > > > > +  @param Lba      The starting logical block index > > > > +                  from which to read. > > > > + > > > > +  @param Offset   Offset into the block at which to begin reading. > > > > + > > > > +  @param NumBytes Pointer to a UINTN. At entry, *NumBytes > > > > +                  contains the total size of the buffer. At > > > > +                  exit, *NumBytes contains the total number of > > > > +                  bytes read. > > > > + > > > > +  @param Buffer   Pointer to a caller-allocated buffer that will > > > > +                  be used to hold the data that is read. > > > > + > > > > +  @retval EFI_SUCCESS         The firmware volume was read successfully, > > > > +                              and contents are in Buffer. > > > > + > > > > +  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA > > > > +                              boundary. On output, NumBytes > > > > +                              contains the total number of bytes > > > > +                              returned in Buffer. > > > > + > > > > +  @retval EFI_ACCESS_DENIED   The firmware volume is in the > > > > +                              ReadDisabled state. > > > > + > > > > +  @retval EFI_DEVICE_ERROR    The block device is not > > > > +                              functioning correctly and could > > > > +                              not be read. > > > I think one new line should be enough. And would it be possible to align the > return codes comments ? What's misaligned here? the parameters and the retval comments? This was pretty much copied from a different driver, so I assumed that was the 'right way'. I can of course align them. > > + > > > > +**/ > > > > +STATIC > > > > +EFI_STATUS > > > > > > +  ReadAddr = Instance->MemBaseAddress; > > > > +  // There's no need to check if the read failed here. The upper EDK2 > > layers > > > > +  // will initialize the flash correctly if the in-memory copy is wrong > > > > +  ReadWriteRpmb ( > ReadWriteRpmb() returns an error code, I think we should return it aswell. There's a reason the return code is not checked here. This is only called in FvbInitialize(). That function will always run, even if the RPMB, the files and filesystem that OP-TEE creates haven't been created yet. In that case the OP-TEE API will return an 'error' which is 'file not found' though. You want to initialize properly with the FVB headers etc and continue with those contents. The code that follows does that, so if we checked the return code and exited early we would never be able to build the flash contents correctly to begin with. In any case after the read the headers are checked for validity/correctness and if an error is found the contents will be rebuilt. So we don't really care about the return here. Worst case scenario the flash is broken and we need to rebuild it. That's what the comment is trying to explain. Is there a better way to initialize the flash and the contents? Is there a callback in EDK2 to explicitly rebuild the flash if an error is found during the Fvbinitiaze phase? > > > > +    SP_SVC_RPMB_READ, > > +  @retval EFI_OUT_OF_RESOURCES      op-tee out of memory [...] > > > > + > > > > + > > > > + > I think one new line should be enough. Ok > > > > [...] > > +    mInstance.MemBaseAddress + > > > > +    PcdGet32 (PcdFlashNvStorageVariableSize) + > > > > +    PcdGet32 (PcdFlashNvStorageFtwWorkingSize) > > > > +    ); > It seems this part is really similar to what is FixupPcd.c:FixPcdMemory(), > maybe this would be worth re-using it. This is calculating the offsets of dynamic memory allocation that 'maps' to our RPMB and it is indeed identical. But since they run into completely different contexts I tried to avoid introducing dependencies between the 2 files. Is that a big problem? > > > > + > > [...] > > +/** > > > > +  This struct is used by the RPMB driver. Since the upper EDK2 layers > > > > +  expect byte addressable memory, we allocate a memory area of certain > > > > +  size and sync it to the hardware on reads/writes. > > > > + > > > > +  @param[in] Signature        Internal signature used to discover the > > instance > > > > +  @param[in] Initialize       Function used to initialize the instance > > > > +  @param[in] Initialized      Set to true if initialized > > > > +  @param[in] FvbProtocol      FVB protocol of the instance > > > > +  @param[in] Handle           Handle to install > > > > +  @param[in] MemBaseAddress   Physical address of the beggining of the > > allocated memory > > > > +  @param[in] BlockSize        Blocksize > > > > +  @param[in] NBlocks          Number of allocated blocks > > I think that for doxygen, '@param[in]' is more for functions declarations. > For structures, it should be as: > > /** >   * This struct is used by the RPMB driver. Since the upper EDK2 layers >   * expect byte addressable memory, we allocate a memory area of certain >   * size and sync it to the hardware on reads/writes. > **/ > struct _MEM_INSTANCE { >     ///  Signature        Internal signature used to discover the instance >     UINT32                              Signature; > > /// Initialize       Function used to initialize the instance >     MEM_INITIALIZE                      Initialize; > > [...] > }; > > Cf: https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/56_declarations_and_types#5-6-3-2-structure-declaration-with-forward-reference-or-self-reference > Ok Thanks /Ilias