BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3108 In preparation for a new interface to be added to the MemEncryptSevLib library that will be used in SEC, create an SEC version of the library. This requires the creation of SEC specific files. Some of the current MemEncryptSevLib functions perform memory allocations which cannot be performed in SEC, so these interfaces will return an error during SEC. Also, the current MemEncryptSevLib library uses some static variables to optimize access to variables, which cannot be used in SEC. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Message-Id: <bc7fa76cc23784ab3f37356b6c10dfec61942c38.1610045305.git.thomas.lendacky@amd.com>
		
			
				
	
	
		
			156 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
 | 
						|
  Secure Encrypted Virtualization (SEV) library helper function
 | 
						|
 | 
						|
  Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/MemEncryptSevLib.h>
 | 
						|
#include <Library/PcdLib.h>
 | 
						|
#include <Register/Amd/Cpuid.h>
 | 
						|
#include <Register/Amd/Msr.h>
 | 
						|
#include <Register/Cpuid.h>
 | 
						|
#include <Uefi/UefiBaseType.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Reads and sets the status of SEV features.
 | 
						|
 | 
						|
  **/
 | 
						|
STATIC
 | 
						|
UINT32
 | 
						|
EFIAPI
 | 
						|
InternalMemEncryptSevStatus (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32                            RegEax;
 | 
						|
  CPUID_MEMORY_ENCRYPTION_INFO_EAX  Eax;
 | 
						|
  BOOLEAN                           ReadSevMsr;
 | 
						|
  SEC_SEV_ES_WORK_AREA              *SevEsWorkArea;
 | 
						|
 | 
						|
  ReadSevMsr = FALSE;
 | 
						|
 | 
						|
  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
 | 
						|
  if (SevEsWorkArea != NULL && SevEsWorkArea->EncryptionMask != 0) {
 | 
						|
    //
 | 
						|
    // The MSR has been read before, so it is safe to read it again and avoid
 | 
						|
    // having to validate the CPUID information.
 | 
						|
    //
 | 
						|
    ReadSevMsr = TRUE;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Check if memory encryption leaf exist
 | 
						|
    //
 | 
						|
    AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
 | 
						|
    if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {
 | 
						|
      //
 | 
						|
      // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)
 | 
						|
      //
 | 
						|
      AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);
 | 
						|
 | 
						|
      if (Eax.Bits.SevBit) {
 | 
						|
        ReadSevMsr = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return ReadSevMsr ? AsmReadMsr32 (MSR_SEV_STATUS) : 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a boolean to indicate whether SEV-ES is enabled.
 | 
						|
 | 
						|
  @retval TRUE           SEV-ES is enabled
 | 
						|
  @retval FALSE          SEV-ES is not enabled
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
MemEncryptSevEsIsEnabled (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  MSR_SEV_STATUS_REGISTER           Msr;
 | 
						|
 | 
						|
  Msr.Uint32 = InternalMemEncryptSevStatus ();
 | 
						|
 | 
						|
  return Msr.Bits.SevEsBit ? TRUE : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a boolean to indicate whether SEV is enabled.
 | 
						|
 | 
						|
  @retval TRUE           SEV is enabled
 | 
						|
  @retval FALSE          SEV is not enabled
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
MemEncryptSevIsEnabled (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  MSR_SEV_STATUS_REGISTER           Msr;
 | 
						|
 | 
						|
  Msr.Uint32 = InternalMemEncryptSevStatus ();
 | 
						|
 | 
						|
  return Msr.Bits.SevBit ? TRUE : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns the SEV encryption mask.
 | 
						|
 | 
						|
  @return  The SEV pagtable encryption mask
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
EFIAPI
 | 
						|
MemEncryptSevGetEncryptionMask (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;
 | 
						|
  SEC_SEV_ES_WORK_AREA              *SevEsWorkArea;
 | 
						|
  UINT64                            EncryptionMask;
 | 
						|
 | 
						|
  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
 | 
						|
  if (SevEsWorkArea != NULL) {
 | 
						|
    EncryptionMask = SevEsWorkArea->EncryptionMask;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)
 | 
						|
    //
 | 
						|
    AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);
 | 
						|
    EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);
 | 
						|
  }
 | 
						|
 | 
						|
  return EncryptionMask;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM
 | 
						|
  Save State Map.
 | 
						|
 | 
						|
  @param[out] BaseAddress     The base address of the lowest-address page that
 | 
						|
                              covers the initial SMRAM Save State Map.
 | 
						|
 | 
						|
  @param[out] NumberOfPages   The number of pages in the page range that covers
 | 
						|
                              the initial SMRAM Save State Map.
 | 
						|
 | 
						|
  @retval RETURN_SUCCESS      BaseAddress and NumberOfPages have been set on
 | 
						|
                              output.
 | 
						|
 | 
						|
  @retval RETURN_UNSUPPORTED  SMM is unavailable.
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
MemEncryptSevLocateInitialSmramSaveStateMapPages (
 | 
						|
  OUT UINTN *BaseAddress,
 | 
						|
  OUT UINTN *NumberOfPages
 | 
						|
  )
 | 
						|
{
 | 
						|
  return RETURN_UNSUPPORTED;
 | 
						|
}
 |