[edk2-devel] [PATCH 09/12] OvmfPkg/MemEncryptSevLib: Address range encryption state interface

Laszlo Ersek lersek at redhat.com
Tue Jan 5 09:48:43 UTC 2021


On 12/15/20 21:51, Lendacky, Thomas wrote:
> From: Tom Lendacky <thomas.lendacky at amd.com>
> 
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3108
> 
> Update the MemEncryptSevLib library to include an interface that can
> report the encryption state on a range of memory. The values will
> represent the range as being unencrypted, encrypted, a mix of unencrypted
> and encrypted, and error (e.g. ranges that aren't mapped).
> 
> Cc: Jordan Justen <jordan.l.justen at intel.com>
> Cc: Laszlo Ersek <lersek at redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel at arm.com>
> Cc: Brijesh Singh <brijesh.singh at amd.com>
> Signed-off-by: Tom Lendacky <thomas.lendacky at amd.com>
> ---
>  .../DxeBaseMemEncryptSevLib.inf               |   1 +
>  .../PeiBaseMemEncryptSevLib.inf               |   1 +
>  .../SecBaseMemEncryptSevLib.inf               |   1 +
>  OvmfPkg/Include/Library/MemEncryptSevLib.h    |  33 +++
>  .../BaseMemEncryptSevLib/X64/VirtualMemory.h  |  35 ++-
>  .../Ia32/MemEncryptSevLib.c                   |  31 ++-
>  .../X64/MemEncryptSevLib.c                    |  32 ++-
>  .../X64/PeiDxeVirtualMemory.c                 |  19 +-
>  .../X64/SecVirtualMemory.c                    |  20 ++
>  .../BaseMemEncryptSevLib/X64/VirtualMemory.c  | 207 ++++++++++++++++++
>  10 files changed, 368 insertions(+), 12 deletions(-)
>  create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c

Acked-by: Laszlo Ersek <lersek at redhat.com>

Thanks,
Laszlo

> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf
> index 390f2d60677f..04728a5dd256 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf
> @@ -34,6 +34,7 @@ [Sources.X64]
>    MemEncryptSevLibInternal.c
>    X64/MemEncryptSevLib.c
>    X64/PeiDxeVirtualMemory.c
> +  X64/VirtualMemory.c
>    X64/VirtualMemory.h
>  
>  [Sources.IA32]
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf
> index cb973fdeb868..4e4f59c0b0b6 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiBaseMemEncryptSevLib.inf
> @@ -34,6 +34,7 @@ [Sources.X64]
>    MemEncryptSevLibInternal.c
>    X64/MemEncryptSevLib.c
>    X64/PeiDxeVirtualMemory.c
> +  X64/VirtualMemory.c
>    X64/VirtualMemory.h
>  
>  [Sources.IA32]
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf
> index b26f739d69fd..79389298a3b3 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptSevLib.inf
> @@ -34,6 +34,7 @@ [Sources.X64]
>    MemEncryptSevLibInternal.c
>    X64/MemEncryptSevLib.c
>    X64/SecVirtualMemory.c
> +  X64/VirtualMemory.c
>    X64/VirtualMemory.h
>  
>  [Sources.IA32]
> diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> index 394065f15bc1..421b2e2c2c1e 100644
> --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
> +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
> @@ -33,6 +33,16 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
>    UINT64   EncryptionMask;
>  } SEC_SEV_ES_WORK_AREA;
>  
> +//
> +// Memory encryption address range states.
> +//
> +typedef enum {
> +  MemEncryptSevAddressRangeUnencrypted,
> +  MemEncryptSevAddressRangeEncrypted,
> +  MemEncryptSevAddressRangeMixed,
> +  MemEncryptSevAddressRangeError,
> +} MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE;
> +
>  /**
>    Returns a boolean to indicate whether SEV-ES is enabled.
>  
> @@ -147,4 +157,27 @@ MemEncryptSevGetEncryptionMask (
>    VOID
>    );
>  
> +/**
> +  Returns the encryption state of the specified virtual address range.
> +
> +  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
> +                                      current CR3)
> +  @param[in]  BaseAddress             Base address to check
> +  @param[in]  Length                  Length of virtual address range
> +
> +  @retval MemEncryptSevAddressRangeUnencrypted  Address range is mapped
> +                                                unencrypted
> +  @retval MemEncryptSevAddressRangeEncrypted    Address range is mapped
> +                                                encrypted
> +  @retval MemEncryptSevAddressRangeMixed        Address range is mapped mixed
> +  @retval MemEncryptSevAddressRangeError        Address range is not mapped
> +**/
> +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
> +EFIAPI
> +MemEncryptSevGetAddressRangeState (
> +  IN PHYSICAL_ADDRESS         Cr3BaseAddress,
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINTN                    Length
> +  );
> +
>  #endif // _MEM_ENCRYPT_SEV_LIB_H_
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
> index 26d26cd922a4..996f94f07ebb 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
> @@ -3,7 +3,7 @@
>    Virtual Memory Management Services to set or clear the memory encryption bit
>  
>    Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> -  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.<BR>
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
>  
> @@ -178,7 +178,17 @@ typedef struct {
>    UINTN           FreePages;
>  } PAGE_TABLE_POOL;
>  
> +/**
> +  Return the pagetable memory encryption mask.
>  
> +  @return  The pagetable memory encryption mask.
> +
> +**/
> +UINT64
> +EFIAPI
> +InternalGetMemEncryptionAddressMask (
> +  VOID
> +  );
>  
>  /**
>    This function clears memory encryption bit for the memory region specified by
> @@ -234,4 +244,27 @@ InternalMemEncryptSevSetMemoryEncrypted (
>    IN  BOOLEAN                 Flush
>    );
>  
> +/**
> +  Returns the encryption state of the specified virtual address range.
> +
> +  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
> +                                      current CR3)
> +  @param[in]  BaseAddress             Base address to check
> +  @param[in]  Length                  Length of virtual address range
> +
> +  @retval MemEncryptSevAddressRangeUnencrypted  Address range is mapped
> +                                                unencrypted
> +  @retval MemEncryptSevAddressRangeEncrypted    Address range is mapped
> +                                                encrypted
> +  @retval MemEncryptSevAddressRangeMixed        Address range is mapped mixed
> +  @retval MemEncryptSevAddressRangeError        Address range is not mapped
> +**/
> +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
> +EFIAPI
> +InternalMemEncryptSevGetAddressRangeState (
> +  IN PHYSICAL_ADDRESS         Cr3BaseAddress,
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINTN                    Length
> +  );
> +
>  #endif
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
> index b4f6e5738e6e..12a5bf495bd7 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
> @@ -2,7 +2,7 @@
>  
>    Secure Encrypted Virtualization (SEV) library helper function
>  
> -  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.<BR>
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
>  
> @@ -82,3 +82,32 @@ MemEncryptSevSetPageEncMask (
>    //
>    return RETURN_UNSUPPORTED;
>  }
> +
> +/**
> +  Returns the encryption state of the specified virtual address range.
> +
> +  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
> +                                      current CR3)
> +  @param[in]  BaseAddress             Base address to check
> +  @param[in]  Length                  Length of virtual address range
> +
> +  @retval MemEncryptSevAddressRangeUnencrypted  Address range is mapped
> +                                                unencrypted
> +  @retval MemEncryptSevAddressRangeEncrypted    Address range is mapped
> +                                                encrypted
> +  @retval MemEncryptSevAddressRangeMixed        Address range is mapped mixed
> +  @retval MemEncryptSevAddressRangeError        Address range is not mapped
> +**/
> +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
> +EFIAPI
> +MemEncryptSevGetAddressRangeState (
> +  IN PHYSICAL_ADDRESS         Cr3BaseAddress,
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINTN                    Length
> +  )
> +{
> +  //
> +  // Memory is always encrypted in 32-bit mode
> +  //
> +  return MemEncryptSevAddressRangeEncrypted;
> +}
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
> index cf0921e21464..4fea6a6be0ac 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
> @@ -2,7 +2,7 @@
>  
>    Secure Encrypted Virtualization (SEV) library helper function
>  
> -  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.<BR>
>  
>    SPDX-License-Identifier: BSD-2-Clause-Patent
>  
> @@ -88,3 +88,33 @@ MemEncryptSevSetPageEncMask (
>             Flush
>             );
>  }
> +
> +/**
> +  Returns the encryption state of the specified virtual address range.
> +
> +  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
> +                                      current CR3)
> +  @param[in]  BaseAddress             Base address to check
> +  @param[in]  Length                  Length of virtual address range
> +
> +  @retval MemEncryptSevAddressRangeUnencrypted  Address range is mapped
> +                                                unencrypted
> +  @retval MemEncryptSevAddressRangeEncrypted    Address range is mapped
> +                                                encrypted
> +  @retval MemEncryptSevAddressRangeMixed        Address range is mapped mixed
> +  @retval MemEncryptSevAddressRangeError        Address range is not mapped
> +**/
> +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
> +EFIAPI
> +MemEncryptSevGetAddressRangeState (
> +  IN PHYSICAL_ADDRESS         Cr3BaseAddress,
> +  IN PHYSICAL_ADDRESS         BaseAddress,
> +  IN UINTN                    Length
> +  )
> +{
> +  return InternalMemEncryptSevGetAddressRangeState (
> +           Cr3BaseAddress,
> +           BaseAddress,
> +           Length
> +           );
> +}
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
> index 3a5bab657bd7..d3455e812bd1 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
> @@ -28,14 +28,14 @@ typedef enum {
>  } MAP_RANGE_MODE;
>  
>  /**
> -  Get the memory encryption mask
> +  Return the pagetable memory encryption mask.
>  
> -  @param[out]      EncryptionMask        contains the pte mask.
> +  @return  The pagetable memory encryption mask.
>  
>  **/
> -STATIC
>  UINT64
> -GetMemEncryptionAddressMask (
> +EFIAPI
> +InternalGetMemEncryptionAddressMask (
>    VOID
>    )
>  {
> @@ -200,7 +200,7 @@ Split2MPageTo4K (
>  
>    PageTableEntry1 = PageTableEntry;
>  
> -  AddressEncMask = GetMemEncryptionAddressMask ();
> +  AddressEncMask = InternalGetMemEncryptionAddressMask ();
>  
>    ASSERT (PageTableEntry != NULL);
>    ASSERT (*PageEntry2M & AddressEncMask);
> @@ -286,7 +286,7 @@ SetPageTablePoolReadOnly (
>    LevelSize[3] = SIZE_1GB;
>    LevelSize[4] = SIZE_512GB;
>  
> -  AddressEncMask  = GetMemEncryptionAddressMask();
> +  AddressEncMask  = InternalGetMemEncryptionAddressMask();
>    PageTable       = (UINT64 *)(UINTN)PageTableBase;
>    PoolUnitSize    = PAGE_TABLE_POOL_UNIT_SIZE;
>  
> @@ -431,7 +431,7 @@ Split1GPageTo2M (
>  
>    PageDirectoryEntry = AllocatePageTableMemory(1);
>  
> -  AddressEncMask = GetMemEncryptionAddressMask ();
> +  AddressEncMask = InternalGetMemEncryptionAddressMask ();
>    ASSERT (PageDirectoryEntry != NULL);
>    ASSERT (*PageEntry1G & AddressEncMask);
>    //
> @@ -485,7 +485,7 @@ SetOrClearCBit(
>  {
>    UINT64      AddressEncMask;
>  
> -  AddressEncMask = GetMemEncryptionAddressMask ();
> +  AddressEncMask = InternalGetMemEncryptionAddressMask ();
>  
>    if (Mode == SetCBit) {
>      *PageTablePointer |= AddressEncMask;
> @@ -527,6 +527,7 @@ DisableReadOnlyPageWriteProtect (
>  /**
>   Enable Write Protect on pages marked as read-only.
>  **/
> +STATIC
>  VOID
>  EnableReadOnlyPageWriteProtect (
>    VOID
> @@ -605,7 +606,7 @@ SetMemoryEncDec (
>    //
>    // Check if we have a valid memory encryption mask
>    //
> -  AddressEncMask = GetMemEncryptionAddressMask ();
> +  AddressEncMask = InternalGetMemEncryptionAddressMask ();
>    if (!AddressEncMask) {
>      return RETURN_ACCESS_DENIED;
>    }
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
> index 5c337ea0b820..bca5e3febb1b 100644
> --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecVirtualMemory.c
> @@ -13,6 +13,26 @@
>  
>  #include "VirtualMemory.h"
>  
> +/**
> +  Return the pagetable memory encryption mask.
> +
> +  @return  The pagetable memory encryption mask.
> +
> +**/
> +UINT64
> +EFIAPI
> +InternalGetMemEncryptionAddressMask (
> +  VOID
> +  )
> +{
> +  UINT64                            EncryptionMask;
> +
> +  EncryptionMask = MemEncryptSevGetEncryptionMask ();
> +  EncryptionMask &= PAGING_1G_ADDRESS_MASK_64;
> +
> +  return EncryptionMask;
> +}
> +
>  /**
>    This function clears memory encryption bit for the memory region specified by
>    PhysicalAddress and Length from the current page table context.
> diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
> new file mode 100644
> index 000000000000..36aabcf556a7
> --- /dev/null
> +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.c
> @@ -0,0 +1,207 @@
> +/** @file
> +
> +  Virtual Memory Management Services to test an address range encryption state
> +
> +  Copyright (c) 2020, AMD Incorporated. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/CpuLib.h>
> +#include <Library/MemEncryptSevLib.h>
> +
> +#include "VirtualMemory.h"
> +
> +/**
> +  Returns the (updated) address range state based upon the page table
> +  entry.
> +
> +  @param[in]  CurrentState            The current address range state
> +  @param[in]  PageDirectoryEntry      The page table entry to check
> +  @param[in]  AddressEncMask          The encryption mask
> +
> +  @retval MemEncryptSevAddressRangeUnencrypted  Address range is mapped
> +                                                unencrypted
> +  @retval MemEncryptSevAddressRangeEncrypted    Address range is mapped
> +                                                encrypted
> +  @retval MemEncryptSevAddressRangeMixed        Address range is mapped mixed
> +**/
> +STATIC
> +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
> +UpdateAddressState (
> +  IN MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE  CurrentState,
> +  IN UINT64                               PageDirectoryEntry,
> +  IN UINT64                               AddressEncMask
> +  )
> +{
> +  if (CurrentState == MemEncryptSevAddressRangeEncrypted) {
> +    if ((PageDirectoryEntry & AddressEncMask) == 0) {
> +      CurrentState = MemEncryptSevAddressRangeMixed;
> +    }
> +  } else if (CurrentState == MemEncryptSevAddressRangeUnencrypted) {
> +    if ((PageDirectoryEntry & AddressEncMask) != 0) {
> +      CurrentState = MemEncryptSevAddressRangeMixed;
> +    }
> +  } else if (CurrentState == MemEncryptSevAddressRangeError) {
> +    //
> +    // First address check, set initial state
> +    //
> +    if ((PageDirectoryEntry & AddressEncMask) == 0) {
> +      CurrentState = MemEncryptSevAddressRangeUnencrypted;
> +    } else {
> +      CurrentState = MemEncryptSevAddressRangeEncrypted;
> +    }
> +  }
> +
> +  return CurrentState;
> +}
> +
> +/**
> +  Returns the encryption state of the specified virtual address range.
> +
> +  @param[in]  Cr3BaseAddress          Cr3 Base Address (if zero then use
> +                                      current CR3)
> +  @param[in]  BaseAddress             Base address to check
> +  @param[in]  Length                  Length of virtual address range
> +
> +  @retval MemEncryptSevAddressRangeUnencrypted  Address range is mapped
> +                                                unencrypted
> +  @retval MemEncryptSevAddressRangeEncrypted    Address range is mapped
> +                                                encrypted
> +  @retval MemEncryptSevAddressRangeMixed        Address range is mapped mixed
> +  @retval MemEncryptSevAddressRangeError        Address range is not mapped
> +**/
> +MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE
> +EFIAPI
> +InternalMemEncryptSevGetAddressRangeState (
> +  IN PHYSICAL_ADDRESS  Cr3BaseAddress,
> +  IN PHYSICAL_ADDRESS  BaseAddress,
> +  IN UINTN             Length
> +  )
> +{
> +  PAGE_MAP_AND_DIRECTORY_POINTER       *PageMapLevel4Entry;
> +  PAGE_MAP_AND_DIRECTORY_POINTER       *PageUpperDirectoryPointerEntry;
> +  PAGE_MAP_AND_DIRECTORY_POINTER       *PageDirectoryPointerEntry;
> +  PAGE_TABLE_1G_ENTRY                  *PageDirectory1GEntry;
> +  PAGE_TABLE_ENTRY                     *PageDirectory2MEntry;
> +  PAGE_TABLE_4K_ENTRY                  *PageTableEntry;
> +  UINT64                               AddressEncMask;
> +  UINT64                               PgTableMask;
> +  PHYSICAL_ADDRESS                     Address;
> +  PHYSICAL_ADDRESS                     AddressEnd;
> +  MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE  State;
> +
> +  //
> +  // If Cr3BaseAddress is not specified then read the current CR3
> +  //
> +  if (Cr3BaseAddress == 0) {
> +    Cr3BaseAddress = AsmReadCr3();
> +  }
> +
> +  AddressEncMask = MemEncryptSevGetEncryptionMask ();
> +  AddressEncMask &= PAGING_1G_ADDRESS_MASK_64;
> +
> +  PgTableMask = AddressEncMask | EFI_PAGE_MASK;
> +
> +  State = MemEncryptSevAddressRangeError;
> +
> +  //
> +  // Encryption is on a page basis, so start at the beginning of the
> +  // virtual address page boundary and walk page-by-page.
> +  //
> +  Address = (PHYSICAL_ADDRESS) (UINTN) BaseAddress & ~EFI_PAGE_MASK;
> +  AddressEnd = (PHYSICAL_ADDRESS)
> +                 (UINTN) (BaseAddress + Length);
> +
> +  while (Address < AddressEnd) {
> +    PageMapLevel4Entry = (VOID*) (Cr3BaseAddress & ~PgTableMask);
> +    PageMapLevel4Entry += PML4_OFFSET (Address);
> +    if (!PageMapLevel4Entry->Bits.Present) {
> +      return MemEncryptSevAddressRangeError;
> +    }
> +
> +    PageDirectory1GEntry = (VOID *) (
> +                             (PageMapLevel4Entry->Bits.PageTableBaseAddress <<
> +                              12) & ~PgTableMask
> +                             );
> +    PageDirectory1GEntry += PDP_OFFSET (Address);
> +    if (!PageDirectory1GEntry->Bits.Present) {
> +      return MemEncryptSevAddressRangeError;
> +    }
> +
> +    //
> +    // If the MustBe1 bit is not 1, it's not actually a 1GB entry
> +    //
> +    if (PageDirectory1GEntry->Bits.MustBe1) {
> +      //
> +      // Valid 1GB page
> +      //
> +      State = UpdateAddressState (
> +                State,
> +                PageDirectory1GEntry->Uint64,
> +                AddressEncMask
> +                );
> +
> +      Address += BIT30;
> +      continue;
> +    }
> +
> +    //
> +    // Actually a PDP
> +    //
> +    PageUpperDirectoryPointerEntry =
> +      (PAGE_MAP_AND_DIRECTORY_POINTER *) PageDirectory1GEntry;
> +    PageDirectory2MEntry =
> +      (VOID *) (
> +        (PageUpperDirectoryPointerEntry->Bits.PageTableBaseAddress <<
> +         12) & ~PgTableMask
> +        );
> +    PageDirectory2MEntry += PDE_OFFSET (Address);
> +    if (!PageDirectory2MEntry->Bits.Present) {
> +      return MemEncryptSevAddressRangeError;
> +    }
> +
> +    //
> +    // If the MustBe1 bit is not a 1, it's not a 2MB entry
> +    //
> +    if (PageDirectory2MEntry->Bits.MustBe1) {
> +      //
> +      // Valid 2MB page
> +      //
> +      State = UpdateAddressState (
> +                State,
> +                PageDirectory2MEntry->Uint64,
> +                AddressEncMask
> +                );
> +
> +      Address += BIT21;
> +      continue;
> +    }
> +
> +    //
> +    // Actually a PMD
> +    //
> +    PageDirectoryPointerEntry =
> +      (PAGE_MAP_AND_DIRECTORY_POINTER *)PageDirectory2MEntry;
> +    PageTableEntry =
> +      (VOID *)(
> +        (PageDirectoryPointerEntry->Bits.PageTableBaseAddress <<
> +         12) & ~PgTableMask
> +        );
> +    PageTableEntry += PTE_OFFSET (Address);
> +    if (!PageTableEntry->Bits.Present) {
> +      return MemEncryptSevAddressRangeError;
> +    }
> +
> +    State = UpdateAddressState (
> +              State,
> +              PageTableEntry->Uint64,
> +              AddressEncMask
> +              );
> +
> +    Address += EFI_PAGE_SIZE;
> +  }
> +
> +  return State;
> +}
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#69687): https://edk2.groups.io/g/devel/message/69687
Mute This Topic: https://groups.io/mt/78986176/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list