On October 12, 2021 4:22 PM, Gerd Hoffmann wrote:
> > +// PageSize is mapped to PageLevel like below:
> > +// 4KB - 0, 2MB - 1
> > +UINT64  mTdxAcceptPageLevelMap[2] = {
> > +  SIZE_4KB,
> > +  SIZE_2MB
> 
> No 1G pages?
TDX: 
https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-module-1.0-public-spec-v0.931.pdf
 
Theoretically there are 3 AcceptPageSize (4KB/2MB/1GB). But currently only 4KB 
and 2MB are supported. See section 22.3.2.
> 
> > +UINTN
> > +GetGpaPageLevel (
> > +  UINT64 PageSize
> 
> Uh, UINT32 is not enough?  Keep the door open for 512G pages?
Thanks for reminder. UINT32 is enough. It will be updated in next version.
> 
> > +{
> > +  UINTN Index;
> > +
> > +  for (Index = 0; Index < sizeof (mTdxAcceptPageLevelMap) / sizeof
> > + (mTdxAcceptPageLevelMap[0]); Index++) {
> 
> There is an ARRAY_SIZE() macro, no need to open code the sizeof() trick.
Thanks for reminder. It will be updated in next version.
> 
> > +    if (mTdxAcceptPageLevelMap[Index] == PageSize) {
> > +      break;
> > +    }
> > +  }
> > +
> > +  return Index;
> > +}
> 
> No error handling (invalid PageSize) here?
> 
> > +/**
> > +  This function accept a pending private page, and initialize the
> > +page to
> > +  all-0 using the TD ephemeral private key.
> > +
> > +  Sometimes TDCALL [TDG.MEM.PAGE.ACCEPT] may return
> > + TDX_EXIT_REASON_PAGE_SIZE_MISMATCH. It indicates the input PageLevel
> > + is  not workable. In this case we need to try to fallback to a
> > + smaller  PageLevel if possible.
> > +
> > +  @param[in]  StartAddress      Guest physical address of the private
> > +                                page to accept.
> > +  @param[in]  NumberOfPages     Number of the pages to be accepted.
> > +  @param[in]  PageSize          GPA page size. Only accept 1G/2M/4K size.
> > +
> > +  @return EFI_SUCCESS           Accept successfully
> > +  @return others                Indicate other errors
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TdAcceptPages (
> > +  IN UINT64  StartAddress,
> > +  IN UINT64  NumberOfPages,
> > +  IN UINT64  PageSize
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +  UINT64      Address;
> > +  UINT64      TdxStatus;
> > +  UINT64      Index;
> > +  UINT64      GpaPageLevel;
> > +  UINT64      PageSize2;
> > +
> > +  Address = StartAddress;
> > +
> > +  GpaPageLevel = (UINT64) GetGpaPageLevel (PageSize);
> 
> Why cast?
Thanks for reminder. The cast is not needed. It will be updated in next version.
> 
> > +  if (GpaPageLevel > sizeof (mTdxAcceptPageLevelMap) / sizeof
> (mTdxAcceptPageLevelMap[0])) {
> > +    DEBUG ((DEBUG_ERROR, "Accept page size must be 4K/2M. Invalid
> > + page size - 0x%llx\n", PageSize));
> 
> Ah.  Errors are catched here.  Well, no.  The check is wrong, it should be 
> ">=" not
> ">".
> 
> Better would be GetGpaPageLevel explicitly returning a specific value (for
> example -1) on error.
You're right. A dumb error ... It will be fixed in the next version.
> 
> > +  Status = EFI_SUCCESS;
> > +  for (Index = 0; Index < NumberOfPages; Index++) {
> > +    TdxStatus = TdCall (TDCALL_TDACCEPTPAGE, Address | GpaPageLevel, 0, 0,
> 0);
> > +    if (TdxStatus != TDX_EXIT_REASON_SUCCESS) {
> > +        if ((TdxStatus & ~0xFFFFULL) ==
> TDX_EXIT_REASON_PAGE_ALREADY_ACCEPTED) {
> > +          //
> > +          // Already accepted
> > +          //
> > +          mNumberOfDuplicatedAcceptedPages++;
> 
> Hmm.  When this happens we have a bug somewhere, right?
> So should this be an assert()?
> Or should we at least log the address?
ASSERT() is not necessary because the code can still run. But we should log the 
address which has been already accepted.
It  will be added in the next version.
> 
> > +#define RTMR_COUNT                  4
> > +#define TD_EXTEND_BUFFER_LEN        (64 + 64)
> > +#define EXTEND_BUFFER_ADDRESS_MASK  0x3f
> > +
> > +
> > +#pragma pack(16)
> > +typedef struct {
> > +  UINT8   Buffer[TD_EXTEND_BUFFER_LEN];
> > +} TDX_EXTEND_BUFFER;
> > +#pragma pack()
> > +
> > +UINT8               *mExtendBufferAddress = NULL;
> > +TDX_EXTEND_BUFFER   mExtendBuffer;
> > +
> > +/**
> > +  TD.RTMR.EXTEND requires 64B-aligned guest physical address of
> > +  48B-extension data. In runtime we walk thru the Buffer to find
> > +  out a 64B-aligned start address.
> 
> Can't you just use __attribute__((aligned(64))) for that?
> 
In the PoC of TDVF I had thought about it. But at last I gave up such solution. 
The reasons are:
1) OVMF/TDVF supports both GCC and VS2019 tool chain. 
__attribute__((aligned(64))) is for GCC. Its counterpart of VS2019 Tool chain 
is __declspec(align(x)).
2) There is the limitation of /ALIGN:32 in the build scripts which means 
aligned 64 exceeds  the /ALIGN 32, unless /ALIGN is updated to 64.
That's why the current solution is used.

Thanks!
Min



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#81883): https://edk2.groups.io/g/devel/message/81883
Mute This Topic: https://groups.io/mt/86085729/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to