From 9f06feb5d2fa43e184690034e70e6d427cf6913d Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 30 Nov 2022 19:41:12 +1100 Subject: OvmfPkg: Add AMD SEV-ES DebugVirtualization feature support The SEV-ES DebugVirtualization feature enables type B swapping of debug registers on #VMEXIT and makes #DB and DR7 intercepts unnecessary and unwanted. When DebugVirtualization is enabled, this stops booting if interaction from the HV. Add new API to PEI, SEC, DXE. This does not change the existing behaviour yet. Cc: Ard Biesheuvel Cc: Erdem Aktas Cc: Gerd Hoffmann Cc: Jiewen Yao Cc: Michael Roth Cc: Min Xu Reviewed-by: Tom Lendacky Signed-off-by: Alexey Kardashevskiy --- Changes: v5: * "rb" from Tom v4: * s/DebugSwap/DebugVirtualization/ --- OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++++++++ .../DxeMemEncryptSevLibInternal.c | 27 +++++++++++++++++++--- .../PeiMemEncryptSevLibInternal.c | 15 ++++++++++++ .../SecMemEncryptSevLibInternal.c | 15 ++++++++++++ OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 8 +++++++ 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h index 4fa9c0d..c565353 100644 --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h @@ -167,6 +167,18 @@ MemEncryptSevGetEncryptionMask ( ); /** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ); + +/** Returns the encryption state of the specified virtual address range. @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c index 4aba007..9947d66 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c @@ -40,19 +40,25 @@ AmdMemEncryptionAttrCheck ( IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr ) { + UINT64 CurrentLevel; + + CurrentLevel = CurrentAttr & CCAttrTypeMask; + switch (Attr) { case CCAttrAmdSev: // // SEV is automatically enabled if SEV-ES or SEV-SNP is active. // - return CurrentAttr >= CCAttrAmdSev; + return CurrentLevel >= CCAttrAmdSev; case CCAttrAmdSevEs: // // SEV-ES is automatically enabled if SEV-SNP is active. // - return CurrentAttr >= CCAttrAmdSevEs; + return CurrentLevel >= CCAttrAmdSevEs; case CCAttrAmdSevSnp: - return CurrentAttr == CCAttrAmdSevSnp; + return CurrentLevel == CCAttrAmdSevSnp; + case CCAttrFeatureAmdSevEsDebugVirtualization: + return !!(CurrentAttr & CCAttrFeatureAmdSevEsDebugVirtualization); default: return FALSE; } @@ -159,3 +165,18 @@ MemEncryptSevGetEncryptionMask ( return mSevEncryptionMask; } + +/** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ) +{ + return ConfidentialComputingGuestHas (CCAttrFeatureAmdSevEsDebugVirtualization); +} diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c index 41d1246..7d823ad 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c @@ -141,3 +141,18 @@ MemEncryptSevGetEncryptionMask ( return SevEsWorkArea->EncryptionMask; } + +/** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ) +{ + return FALSE; +} diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c index 27148c7..33a326a 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c @@ -143,6 +143,21 @@ MemEncryptSevGetEncryptionMask ( } /** + Returns a boolean to indicate whether DebugVirtualization is enabled. + + @retval TRUE DebugVirtualization is enabled + @retval FALSE DebugVirtualization is not enabled +**/ +BOOLEAN +EFIAPI +MemEncryptSevEsDebugVirtualizationIsEnabled ( + VOID + ) +{ + return FALSE; +} + +/** Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM Save State Map. diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c index da8f1e5..2031fa9 100644 --- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c +++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c @@ -1609,6 +1609,10 @@ Dr7WriteExit ( UINT64 *Register; UINT64 Status; + if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) { + return UnsupportedExit (Ghcb, Regs, InstructionData); + } + Ext = &InstructionData->Ext; SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1); @@ -1659,6 +1663,10 @@ Dr7ReadExit ( SEV_ES_PER_CPU_DATA *SevEsData; UINT64 *Register; + if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) { + return UnsupportedExit (Ghcb, Regs, InstructionData); + } + Ext = &InstructionData->Ext; SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1); -- cgit v1.1