diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf index f613bb314f..35b7d519d9 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf @@ -58,3 +58,4 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask + gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c index 15fcd55295..4aba0075b9 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c @@ -16,83 +16,84 @@ #include #include #include +#include -STATIC BOOLEAN mSevStatus = FALSE; -STATIC BOOLEAN mSevEsStatus = FALSE; -STATIC BOOLEAN mSevSnpStatus = FALSE; -STATIC BOOLEAN mSevStatusChecked = FALSE; - +STATIC UINT64 mCurrentAttr = 0; +STATIC BOOLEAN mCurrentAttrRead = FALSE; STATIC UINT64 mSevEncryptionMask = 0; STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; /** - Reads and sets the status of SEV features. + The function check if the specified Attr is set. - **/ + @param[in] CurrentAttr The current attribute. + @param[in] Attr The attribute to check. + + @retval TRUE The specified Attr is set. + @retval FALSE The specified Attr is not set. + +**/ STATIC -VOID -EFIAPI -InternalMemEncryptSevStatus ( - VOID +BOOLEAN +AmdMemEncryptionAttrCheck ( + IN UINT64 CurrentAttr, + IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr ) { - UINT32 RegEax; - MSR_SEV_STATUS_REGISTER Msr; - CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax; - BOOLEAN ReadSevMsr; - UINT64 EncryptionMask; - - ReadSevMsr = FALSE; - - EncryptionMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask); - if (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) { + switch (Attr) { + case CCAttrAmdSev: // - // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported) + // SEV is automatically enabled if SEV-ES or SEV-SNP is active. // - AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL); + return CurrentAttr >= CCAttrAmdSev; + case CCAttrAmdSevEs: + // + // SEV-ES is automatically enabled if SEV-SNP is active. + // + return CurrentAttr >= CCAttrAmdSevEs; + case CCAttrAmdSevSnp: + return CurrentAttr == CCAttrAmdSevSnp; + default: + return FALSE; + } +} - if (Eax.Bits.SevBit) { - ReadSevMsr = TRUE; - } - } +/** + Check if the specified confidential computing attribute is active. + + @param[in] Attr The attribute to check. + + @retval TRUE The specified Attr is active. + @retval FALSE The specified Attr is not active. + +**/ +STATIC +BOOLEAN +EFIAPI +ConfidentialComputingGuestHas ( + IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr + ) +{ + // + // Get the current CC attribute. + // + // We avoid reading the PCD on every check because this routine could be indirectly + // called during the virtual pointer conversion. And its not safe to access the + // PCDs during the virtual pointer conversion. + // + if (!mCurrentAttrRead) { + mCurrentAttr = PcdGet64 (PcdConfidentialComputingGuestAttr); + mCurrentAttrRead = TRUE; } - if (ReadSevMsr) { - // - // Check MSR_0xC0010131 Bit 0 (Sev Enabled) - // - Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS); - if (Msr.Bits.SevBit) { - mSevStatus = TRUE; - } - - // - // Check MSR_0xC0010131 Bit 1 (Sev-Es Enabled) - // - if (Msr.Bits.SevEsBit) { - mSevEsStatus = TRUE; - } - - // - // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled) - // - if (Msr.Bits.SevSnpBit) { - mSevSnpStatus = TRUE; - } + // + // If attr is for the AMD group then call AMD specific checks. + // + if (((RShiftU64 (mCurrentAttr, 8)) & 0xff) == 1) { + return AmdMemEncryptionAttrCheck (mCurrentAttr, Attr); } - mSevStatusChecked = TRUE; + return (mCurrentAttr == Attr); } /** @@ -107,11 +108,7 @@ MemEncryptSevSnpIsEnabled ( VOID ) { - if (!mSevStatusChecked) { - InternalMemEncryptSevStatus (); - } - - return mSevSnpStatus; + return ConfidentialComputingGuestHas (CCAttrAmdSevSnp); } /** @@ -126,11 +123,7 @@ MemEncryptSevEsIsEnabled ( VOID ) { - if (!mSevStatusChecked) { - InternalMemEncryptSevStatus (); - } - - return mSevEsStatus; + return ConfidentialComputingGuestHas (CCAttrAmdSevEs); } /** @@ -145,11 +138,7 @@ MemEncryptSevIsEnabled ( VOID ) { - if (!mSevStatusChecked) { - InternalMemEncryptSevStatus (); - } - - return mSevStatus; + return ConfidentialComputingGuestHas (CCAttrAmdSev); } /** diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf index 50c83859d7..714da33237 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf @@ -58,6 +58,7 @@ [FixedPcd] gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecValidatedEnd diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c index d68ff08c3e..3f8f91a5da 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c @@ -17,82 +17,51 @@ #include #include -STATIC BOOLEAN mSevStatus = FALSE; -STATIC BOOLEAN mSevEsStatus = FALSE; -STATIC BOOLEAN mSevSnpStatus = FALSE; -STATIC BOOLEAN mSevStatusChecked = FALSE; - -STATIC UINT64 mSevEncryptionMask = 0; -STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE; - /** - Reads and sets the status of SEV features. + Read the workarea to determine whether SEV is enabled. If enabled, + then return the SevEsWorkArea pointer. **/ STATIC -VOID +SEC_SEV_ES_WORK_AREA * +EFIAPI +GetSevEsWorkArea ( + VOID + ) +{ + OVMF_WORK_AREA *WorkArea; + + WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase); + + // + // If its not SEV guest then SevEsWorkArea is not valid. + // + if ((WorkArea == NULL) || (WorkArea->Header.GuestType != GUEST_TYPE_AMD_SEV)) { + return NULL; + } + + return (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase); +} + +/** + Read the SEV Status MSR value from the workarea + + **/ +STATIC +UINT32 EFIAPI InternalMemEncryptSevStatus ( VOID ) { - UINT32 RegEax; - MSR_SEV_STATUS_REGISTER Msr; - CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax; - BOOLEAN ReadSevMsr; - SEC_SEV_ES_WORK_AREA *SevEsWorkArea; + 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; - } - } + SevEsWorkArea = GetSevEsWorkArea (); + if (SevEsWorkArea == NULL) { + return 0; } - if (ReadSevMsr) { - // - // Check MSR_0xC0010131 Bit 0 (Sev Enabled) - // - Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS); - if (Msr.Bits.SevBit) { - mSevStatus = TRUE; - } - - // - // Check MSR_0xC0010131 Bit 1 (Sev-Es Enabled) - // - if (Msr.Bits.SevEsBit) { - mSevEsStatus = TRUE; - } - - // - // Check MSR_0xC0010131 Bit 2 (Sev-Snp Enabled) - // - if (Msr.Bits.SevSnpBit) { - mSevSnpStatus = TRUE; - } - } - - mSevStatusChecked = TRUE; + return (UINT32)(UINTN)SevEsWorkArea->SevStatusMsrValue; } /** @@ -107,11 +76,11 @@ MemEncryptSevSnpIsEnabled ( VOID ) { - if (!mSevStatusChecked) { - InternalMemEncryptSevStatus (); - } + MSR_SEV_STATUS_REGISTER Msr; - return mSevSnpStatus; + Msr.Uint32 = InternalMemEncryptSevStatus (); + + return Msr.Bits.SevSnpBit ? TRUE : FALSE; } /** @@ -126,11 +95,11 @@ MemEncryptSevEsIsEnabled ( VOID ) { - if (!mSevStatusChecked) { - InternalMemEncryptSevStatus (); - } + MSR_SEV_STATUS_REGISTER Msr; - return mSevEsStatus; + Msr.Uint32 = InternalMemEncryptSevStatus (); + + return Msr.Bits.SevEsBit ? TRUE : FALSE; } /** @@ -145,11 +114,11 @@ MemEncryptSevIsEnabled ( VOID ) { - if (!mSevStatusChecked) { - InternalMemEncryptSevStatus (); - } + MSR_SEV_STATUS_REGISTER Msr; - return mSevStatus; + Msr.Uint32 = InternalMemEncryptSevStatus (); + + return Msr.Bits.SevBit ? TRUE : FALSE; } /** @@ -163,24 +132,12 @@ MemEncryptSevGetEncryptionMask ( VOID ) { - if (!mSevEncryptionMaskSaved) { - SEC_SEV_ES_WORK_AREA *SevEsWorkArea; + SEC_SEV_ES_WORK_AREA *SevEsWorkArea; - SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase); - if (SevEsWorkArea != NULL) { - mSevEncryptionMask = SevEsWorkArea->EncryptionMask; - } else { - CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx; - - // - // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position) - // - AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL); - mSevEncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits); - } - - mSevEncryptionMaskSaved = TRUE; + SevEsWorkArea = GetSevEsWorkArea (); + if (SevEsWorkArea == NULL) { + return 0; } - return mSevEncryptionMask; + return SevEsWorkArea->EncryptionMask; } diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf index 939af0a91e..284e5acc11 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf @@ -52,3 +52,4 @@ [FixedPcd] gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c index 5d912b2a4a..80aceba01b 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c @@ -18,7 +18,33 @@ #include /** - Reads and sets the status of SEV features. + Read the workarea to determine whether SEV is enabled. If enabled, + then return the SevEsWorkArea pointer. + + **/ +STATIC +SEC_SEV_ES_WORK_AREA * +EFIAPI +GetSevEsWorkArea ( + VOID + ) +{ + OVMF_WORK_AREA *WorkArea; + + WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase); + + // + // If its not SEV guest then SevEsWorkArea is not valid. + // + if ((WorkArea == NULL) || (WorkArea->Header.GuestType != GUEST_TYPE_AMD_SEV)) { + return NULL; + } + + return (SEC_SEV_ES_WORK_AREA *)FixedPcdGet32 (PcdSevEsWorkAreaBase); +} + +/** + Read the SEV Status MSR value from the workarea **/ STATIC @@ -28,38 +54,14 @@ InternalMemEncryptSevStatus ( VOID ) { - UINT32 RegEax; - CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax; - BOOLEAN ReadSevMsr; - SEC_SEV_ES_WORK_AREA *SevEsWorkArea; + 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; - } - } + SevEsWorkArea = GetSevEsWorkArea (); + if (SevEsWorkArea == NULL) { + return 0; } - return ReadSevMsr ? AsmReadMsr32 (MSR_SEV_STATUS) : 0; + return (UINT32)(UINTN)SevEsWorkArea->SevStatusMsrValue; } /** @@ -130,22 +132,14 @@ MemEncryptSevGetEncryptionMask ( VOID ) { - CPUID_MEMORY_ENCRYPTION_INFO_EBX Ebx; - SEC_SEV_ES_WORK_AREA *SevEsWorkArea; - UINT64 EncryptionMask; + SEC_SEV_ES_WORK_AREA *SevEsWorkArea; - 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); + SevEsWorkArea = GetSevEsWorkArea (); + if (SevEsWorkArea == NULL) { + return 0; } - return EncryptionMask; + return SevEsWorkArea->EncryptionMask; } /**