\r
[Pcd]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask\r
+ gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr\r
#include <Register/Amd/Msr.h>\r
#include <Register/Cpuid.h>\r
#include <Uefi/UefiBaseType.h>\r
+#include <ConfidentialComputingGuestAttr.h>\r
\r
-STATIC BOOLEAN mSevStatus = FALSE;\r
-STATIC BOOLEAN mSevEsStatus = FALSE;\r
-STATIC BOOLEAN mSevSnpStatus = FALSE;\r
-STATIC BOOLEAN mSevStatusChecked = FALSE;\r
-\r
+STATIC UINT64 mCurrentAttr = 0;\r
+STATIC BOOLEAN mCurrentAttrRead = FALSE;\r
STATIC UINT64 mSevEncryptionMask = 0;\r
STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;\r
\r
/**\r
- Reads and sets the status of SEV features.\r
+ The function check if the specified Attr is set.\r
+\r
+ @param[in] CurrentAttr The current attribute.\r
+ @param[in] Attr The attribute to check.\r
\r
- **/\r
+ @retval TRUE The specified Attr is set.\r
+ @retval FALSE The specified Attr is not set.\r
+\r
+**/\r
STATIC\r
-VOID\r
-EFIAPI\r
-InternalMemEncryptSevStatus (\r
- VOID\r
+BOOLEAN\r
+AmdMemEncryptionAttrCheck (\r
+ IN UINT64 CurrentAttr,\r
+ IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr\r
)\r
{\r
- UINT32 RegEax;\r
- MSR_SEV_STATUS_REGISTER Msr;\r
- CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;\r
- BOOLEAN ReadSevMsr;\r
- UINT64 EncryptionMask;\r
-\r
- ReadSevMsr = FALSE;\r
-\r
- EncryptionMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);\r
- if (EncryptionMask != 0) {\r
- //\r
- // The MSR has been read before, so it is safe to read it again and avoid\r
- // having to validate the CPUID information.\r
- //\r
- ReadSevMsr = TRUE;\r
- } else {\r
- //\r
- // Check if memory encryption leaf exist\r
- //\r
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
- if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {\r
+ switch (Attr) {\r
+ case CCAttrAmdSev:\r
//\r
- // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)\r
+ // SEV is automatically enabled if SEV-ES or SEV-SNP is active.\r
//\r
- AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
+ return CurrentAttr >= CCAttrAmdSev;\r
+ case CCAttrAmdSevEs:\r
+ //\r
+ // SEV-ES is automatically enabled if SEV-SNP is active.\r
+ //\r
+ return CurrentAttr >= CCAttrAmdSevEs;\r
+ case CCAttrAmdSevSnp:\r
+ return CurrentAttr == CCAttrAmdSevSnp;\r
+ default:\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Check if the specified confidential computing attribute is active.\r
+\r
+ @param[in] Attr The attribute to check.\r
\r
- if (Eax.Bits.SevBit) {\r
- ReadSevMsr = TRUE;\r
- }\r
- }\r
+ @retval TRUE The specified Attr is active.\r
+ @retval FALSE The specified Attr is not active.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+ConfidentialComputingGuestHas (\r
+ IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr\r
+ )\r
+{\r
+ //\r
+ // Get the current CC attribute.\r
+ //\r
+ // We avoid reading the PCD on every check because this routine could be indirectly\r
+ // called during the virtual pointer conversion. And its not safe to access the\r
+ // PCDs during the virtual pointer conversion.\r
+ //\r
+ if (!mCurrentAttrRead) {\r
+ mCurrentAttr = PcdGet64 (PcdConfidentialComputingGuestAttr);\r
+ mCurrentAttrRead = TRUE;\r
}\r
\r
- if (ReadSevMsr) {\r
- //\r
- // Check MSR_0xC0010131 Bit 0 (Sev Enabled)\r
- //\r
- Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);\r
- if (Msr.Bits.SevBit) {\r
- mSevStatus = TRUE;\r
- }\r
-\r
- //\r
- // Check MSR_0xC0010131 Bit 1 (Sev-Es Enabled)\r
- //\r
- if (Msr.Bits.SevEsBit) {\r
- mSevEsStatus = TRUE;\r
- }\r
-\r
- //\r
- // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)\r
- //\r
- if (Msr.Bits.SevSnpBit) {\r
- mSevSnpStatus = TRUE;\r
- }\r
+ //\r
+ // If attr is for the AMD group then call AMD specific checks.\r
+ //\r
+ if (((RShiftU64 (mCurrentAttr, 8)) & 0xff) == 1) {\r
+ return AmdMemEncryptionAttrCheck (mCurrentAttr, Attr);\r
}\r
\r
- mSevStatusChecked = TRUE;\r
+ return (mCurrentAttr == Attr);\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevStatusChecked) {\r
- InternalMemEncryptSevStatus ();\r
- }\r
-\r
- return mSevSnpStatus;\r
+ return ConfidentialComputingGuestHas (CCAttrAmdSevSnp);\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevStatusChecked) {\r
- InternalMemEncryptSevStatus ();\r
- }\r
-\r
- return mSevEsStatus;\r
+ return ConfidentialComputingGuestHas (CCAttrAmdSevEs);\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevStatusChecked) {\r
- InternalMemEncryptSevStatus ();\r
- }\r
-\r
- return mSevStatus;\r
+ return ConfidentialComputingGuestHas (CCAttrAmdSev);\r
}\r
\r
/**\r
\r
[FixedPcd]\r
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecValidatedEnd\r
#include <Register/Cpuid.h>\r
#include <Uefi/UefiBaseType.h>\r
\r
-STATIC BOOLEAN mSevStatus = FALSE;\r
-STATIC BOOLEAN mSevEsStatus = FALSE;\r
-STATIC BOOLEAN mSevSnpStatus = FALSE;\r
-STATIC BOOLEAN mSevStatusChecked = FALSE;\r
+/**\r
+ Read the workarea to determine whether SEV is enabled. If enabled,\r
+ then return the SevEsWorkArea pointer.\r
+\r
+ **/\r
+STATIC\r
+SEC_SEV_ES_WORK_AREA *\r
+EFIAPI\r
+GetSevEsWorkArea (\r
+ VOID\r
+ )\r
+{\r
+ OVMF_WORK_AREA *WorkArea;\r
+\r
+ WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);\r
+\r
+ //\r
+ // If its not SEV guest then SevEsWorkArea is not valid.\r
+ //\r
+ if ((WorkArea == NULL) || (WorkArea->Header.GuestType != GUEST_TYPE_AMD_SEV)) {\r
+ return NULL;\r
+ }\r
\r
-STATIC UINT64 mSevEncryptionMask = 0;\r
-STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;\r
+ return (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
+}\r
\r
/**\r
- Reads and sets the status of SEV features.\r
+ Read the SEV Status MSR value from the workarea\r
\r
**/\r
STATIC\r
-VOID\r
+UINT32\r
EFIAPI\r
InternalMemEncryptSevStatus (\r
VOID\r
)\r
{\r
- UINT32 RegEax;\r
- MSR_SEV_STATUS_REGISTER Msr;\r
- CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;\r
- BOOLEAN ReadSevMsr;\r
- SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
-\r
- ReadSevMsr = FALSE;\r
-\r
- SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
- if ((SevEsWorkArea != NULL) && (SevEsWorkArea->EncryptionMask != 0)) {\r
- //\r
- // The MSR has been read before, so it is safe to read it again and avoid\r
- // having to validate the CPUID information.\r
- //\r
- ReadSevMsr = TRUE;\r
- } else {\r
- //\r
- // Check if memory encryption leaf exist\r
- //\r
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
- if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {\r
- //\r
- // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)\r
- //\r
- AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
-\r
- if (Eax.Bits.SevBit) {\r
- ReadSevMsr = TRUE;\r
- }\r
- }\r
- }\r
+ SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
\r
- if (ReadSevMsr) {\r
- //\r
- // Check MSR_0xC0010131 Bit 0 (Sev Enabled)\r
- //\r
- Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);\r
- if (Msr.Bits.SevBit) {\r
- mSevStatus = TRUE;\r
- }\r
-\r
- //\r
- // Check MSR_0xC0010131 Bit 1 (Sev-Es Enabled)\r
- //\r
- if (Msr.Bits.SevEsBit) {\r
- mSevEsStatus = TRUE;\r
- }\r
-\r
- //\r
- // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled)\r
- //\r
- if (Msr.Bits.SevSnpBit) {\r
- mSevSnpStatus = TRUE;\r
- }\r
+ SevEsWorkArea = GetSevEsWorkArea ();\r
+ if (SevEsWorkArea == NULL) {\r
+ return 0;\r
}\r
\r
- mSevStatusChecked = TRUE;\r
+ return (UINT32)(UINTN)SevEsWorkArea->SevStatusMsrValue;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevStatusChecked) {\r
- InternalMemEncryptSevStatus ();\r
- }\r
+ MSR_SEV_STATUS_REGISTER Msr;\r
+\r
+ Msr.Uint32 = InternalMemEncryptSevStatus ();\r
\r
- return mSevSnpStatus;\r
+ return Msr.Bits.SevSnpBit ? TRUE : FALSE;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevStatusChecked) {\r
- InternalMemEncryptSevStatus ();\r
- }\r
+ MSR_SEV_STATUS_REGISTER Msr;\r
+\r
+ Msr.Uint32 = InternalMemEncryptSevStatus ();\r
\r
- return mSevEsStatus;\r
+ return Msr.Bits.SevEsBit ? TRUE : FALSE;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevStatusChecked) {\r
- InternalMemEncryptSevStatus ();\r
- }\r
+ MSR_SEV_STATUS_REGISTER Msr;\r
\r
- return mSevStatus;\r
+ Msr.Uint32 = InternalMemEncryptSevStatus ();\r
+\r
+ return Msr.Bits.SevBit ? TRUE : FALSE;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- if (!mSevEncryptionMaskSaved) {\r
- SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
-\r
- SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
- if (SevEsWorkArea != NULL) {\r
- mSevEncryptionMask = SevEsWorkArea->EncryptionMask;\r
- } else {\r
- CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx;\r
-\r
- //\r
- // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)\r
- //\r
- AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);\r
- mSevEncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);\r
- }\r
-\r
- mSevEncryptionMaskSaved = TRUE;\r
+ SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
+\r
+ SevEsWorkArea = GetSevEsWorkArea ();\r
+ if (SevEsWorkArea == NULL) {\r
+ return 0;\r
}\r
\r
- return mSevEncryptionMask;\r
+ return SevEsWorkArea->EncryptionMask;\r
}\r
\r
[FixedPcd]\r
gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase\r
#include <Uefi/UefiBaseType.h>\r
\r
/**\r
- Reads and sets the status of SEV features.\r
+ Read the workarea to determine whether SEV is enabled. If enabled,\r
+ then return the SevEsWorkArea pointer.\r
+\r
+ **/\r
+STATIC\r
+SEC_SEV_ES_WORK_AREA *\r
+EFIAPI\r
+GetSevEsWorkArea (\r
+ VOID\r
+ )\r
+{\r
+ OVMF_WORK_AREA *WorkArea;\r
+\r
+ WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);\r
+\r
+ //\r
+ // If its not SEV guest then SevEsWorkArea is not valid.\r
+ //\r
+ if ((WorkArea == NULL) || (WorkArea->Header.GuestType != GUEST_TYPE_AMD_SEV)) {\r
+ return NULL;\r
+ }\r
+\r
+ return (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
+}\r
+\r
+/**\r
+ Read the SEV Status MSR value from the workarea\r
\r
**/\r
STATIC\r
VOID\r
)\r
{\r
- UINT32 RegEax;\r
- CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;\r
- BOOLEAN ReadSevMsr;\r
- SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
-\r
- ReadSevMsr = FALSE;\r
-\r
- SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
- if ((SevEsWorkArea != NULL) && (SevEsWorkArea->EncryptionMask != 0)) {\r
- //\r
- // The MSR has been read before, so it is safe to read it again and avoid\r
- // having to validate the CPUID information.\r
- //\r
- ReadSevMsr = TRUE;\r
- } else {\r
- //\r
- // Check if memory encryption leaf exist\r
- //\r
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
- if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {\r
- //\r
- // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)\r
- //\r
- AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
-\r
- if (Eax.Bits.SevBit) {\r
- ReadSevMsr = TRUE;\r
- }\r
- }\r
+ SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
+\r
+ SevEsWorkArea = GetSevEsWorkArea ();\r
+ if (SevEsWorkArea == NULL) {\r
+ return 0;\r
}\r
\r
- return ReadSevMsr ? AsmReadMsr32 (MSR_SEV_STATUS) : 0;\r
+ return (UINT32)(UINTN)SevEsWorkArea->SevStatusMsrValue;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx;\r
- SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
- UINT64 EncryptionMask;\r
-\r
- SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase);\r
- if (SevEsWorkArea != NULL) {\r
- EncryptionMask = SevEsWorkArea->EncryptionMask;\r
- } else {\r
- //\r
- // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)\r
- //\r
- AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);\r
- EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);\r
+ SEC_SEV_ES_WORK_AREA *SevEsWorkArea;\r
+\r
+ SevEsWorkArea = GetSevEsWorkArea ();\r
+ if (SevEsWorkArea == NULL) {\r
+ return 0;\r
}\r
\r
- return EncryptionMask;\r
+ return SevEsWorkArea->EncryptionMask;\r
}\r
\r
/**\r