Re: [edk2-devel] [PATCH 1/3] OvmfPkg/PlatformInitLib: Detect FlashNvVarStore before validate it

2024-07-18 Thread Lendacky, Thomas via groups.io
On 7/16/24 21:30, 韩里洋 wrote:
> Hi Tom,
> 
> 
> 
> 
> Thank you for your response.
> 
> In fact, I'm unable to proceed with the development of the fix patch locally 
> as I don't have a SEV-SNP hardware for experimentation. However, it has 
> proven to be crucial for effectively testing and completing the patch.
> 
> Given your expertise and potentially available hardware, would your team be 
> able to take over the fixing of this issue? (bugzilla: 
> https://bugzilla.tianocore.org/show_bug.cgi?id=4807 )

Secure Boot is not supported under SEV-ES and SEV-SNP because SMM is
required in order for Secure Boot to be secure. And SMM is not supported
under SEV-ES and SEV-SNP because the hypervisor is not allowed to alter
the vCPU register state that is needed to use SMM.

Thanks,
Tom

> 
> Thank you very much for your time and consideration.
> 
> Best regards,
> 
> hanliyang
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119977): https://edk2.groups.io/g/devel/message/119977
Mute This Topic: https://groups.io/mt/107212942/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 1/3] OvmfPkg/PlatformInitLib: Detect FlashNvVarStore before validate it

2024-07-15 Thread Lendacky, Thomas via groups.io
On 7/15/24 09:15, Tom Lendacky wrote:
> On 7/14/24 07:24, wojiaohanliy...@163.com wrote:
>> From: hanliyang 
>>
>> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4807
>>
>> The commit 4f173db8b45b ("OvmfPkg/PlatformInitLib: Add functions for
>> EmuVariableNvStore") rename the function from TdxValidateCfv to
>> PlatformValidateNvVarStore.
>>
>> PlatformValidateNvVarStore is placed in the PlatformInitLib and is used
>> in the case that OVMF is launched with -bios parameter and to validate
>> the integrity of FlashNvVarStore. But if we launch a VM without
>> FlashNvVarStore, the PlatformValidateNvVarStore will fail to validate
>> the integrity and will trigger ASSERT (FALSE) in
>> PlatformInitEmuVariableNvStore.
>>
>> In order to prevent calls to PlatformValidateNvVarStore in the case lack
>> of FlashNvVarStore, we should detect FlashNvVarStore before calls to
>> PlatformValidateNvVarStore. If fail to detect FlashNvVarStore, we should
>> return don't initialize the EmuVariableNvStore, otherwise calls to
>> PlatformValidateNvVarStore and initialize the EmuVariableNvStore when
>> succeed to validate the integrity of NvVarStore.
>>
> 
> While Secure Boot isn't supported at the moment for SEV-ES / SEV-SNP,
> this will cause a boot failure for those types of VMs should it be
> enabled.
> 
> SEV-ES results in:
> 
> Invalid MMIO opcode (AF)
> ASSERT [SecMain] 
> /root/kernels/ovmf-build-X64/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c(498):
>  ((BOOLEAN)(0==1))
> 
> while SEV-SNP just terminates with an error in Qemu.

My bad, that was before this patch was applied. After applying this
patch, I receive:

SEV-ES:

MMIO using encrypted memory: FFC0
 X64 Exception Type - 0D(#GP - General Protection)  CPU Apic ID -  


SEV-SNP just terminates as before.

So maybe you need patch #3 to be the first patch in order to
maintain git bisection.

But after applying all 3 patches, SEV-SNP self terminates for an
unsupported #VC error code - 0x404. 0x404 is from accessing a page
as encrypted, but it has not been validated.

Thanks,
Tom

> 
> I haven't looked into what the cause is at this time.
> 
> Thanks,
> Tom
> 
>> Fixes: 4f173db8b45b ("OvmfPkg/PlatformInitLib: Add functions for 
>> EmuVariableNvStore")
>> Signed-off-by: hanliyang 
>> ---
>>  OvmfPkg/Library/PlatformInitLib/Platform.c| 47 +++
>>  .../PlatformInitLib/PlatformInitLib.inf   |  1 +
>>  2 files changed, 48 insertions(+)
>>
>> diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c 
>> b/OvmfPkg/Library/PlatformInitLib/Platform.c
>> index f48bf16ae3..0a720a4c2c 100644
>> --- a/OvmfPkg/Library/PlatformInitLib/Platform.c
>> +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c
>> @@ -895,6 +895,16 @@ PlatformReserveEmuVariableNvStore (
>>return VariableStore;
>>  }
>>  
>> +#define WRITE_BYTE_CMD   0x10
>> +#define BLOCK_ERASE_CMD  0x20
>> +#define CLEAR_STATUS_CMD 0x50
>> +#define READ_STATUS_CMD  0x70
>> +#define READ_DEVID_CMD   0x90
>> +#define BLOCK_ERASE_CONFIRM_CMD  0xd0
>> +#define READ_ARRAY_CMD   0xff
>> +
>> +#define CLEARED_ARRAY_STATUS  0x00
>> +
>>  /**
>>   When OVMF is lauched with -bios parameter, UEFI variables will be
>>   partially emulated, and non-volatile variables may lose their contents
>> @@ -928,6 +938,43 @@ PlatformInitEmuVariableNvStore (
>>Size = (UINT32)PcdGet32 (PcdFlashNvStorageVariableSize);
>>ASSERT (Size < EmuVariableNvStoreSize);
>>  
>> +  //
>> +  // If launch a VM without OvmfFlashNvStorage device, then we'll fail
>> +  // to check the integrity of NvVarStore and trigger ASSERT (FALSE).
>> +  // So, we should detect the OvmfFlashNvStorage before calls to
>> +  // PlatformValidateNvVarStore(). If fail to detect OvmfFlashNvStorage,
>> +  // we should return and don't initialize the EmuVariableNvStore,
>> +  // otherwise calls to PlatformValidateNvVarStore() and initialize the
>> +  // EmuVariableNvStore when succeed to check the integrity of
>> +  // NvVarStore.
>> +  //
>> +  // This method to detect the OvmfFlashNvStorage here references
>> +  // OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c.
>> +  //
>> +  volatile UINT8  *Ptr;
>> +
>> +  UINTN  BlockSize;
>> +  UINTN  Offset;
>> +  UINT8  ProbeUint8;
>> +
>> +  BlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
>> +
>> +  for (Offset = 0; Offset < BlockSize; Offset++) {
>> +Ptr= Base + Offset;
>> +ProbeUint8 = *Ptr;
>> +if ((ProbeUint8 != CLEAR_STATUS_CMD) &&
>> +(ProbeUint8 != READ_STATUS_CMD) &&
>> +(ProbeUint8 != CLEARED_ARRAY_STATUS))
>> +{
>> +  break;
>> +}
>> +  }
>> +
>> +  if (Offset >= BlockSize) {
>> +DEBUG ((DEBUG_INFO, "OvmfFlashNvStorage: Failed to find probe 
>> location\n"));
>> +return EFI_INVALID_PARAMETER;
>> +  }
>> +
>>if (!PlatformValidateNvVarStore (Base, PcdGet32 (PcdCfvRawDataSize))) {
>>  ASSERT (FALSE);
>>  return EFI_INVALID_PARAMETER;
>> diff --git 

Re: [edk2-devel] [PATCH 1/3] OvmfPkg/PlatformInitLib: Detect FlashNvVarStore before validate it

2024-07-15 Thread Lendacky, Thomas via groups.io
On 7/14/24 07:24, wojiaohanliy...@163.com wrote:
> From: hanliyang 
> 
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4807
> 
> The commit 4f173db8b45b ("OvmfPkg/PlatformInitLib: Add functions for
> EmuVariableNvStore") rename the function from TdxValidateCfv to
> PlatformValidateNvVarStore.
> 
> PlatformValidateNvVarStore is placed in the PlatformInitLib and is used
> in the case that OVMF is launched with -bios parameter and to validate
> the integrity of FlashNvVarStore. But if we launch a VM without
> FlashNvVarStore, the PlatformValidateNvVarStore will fail to validate
> the integrity and will trigger ASSERT (FALSE) in
> PlatformInitEmuVariableNvStore.
> 
> In order to prevent calls to PlatformValidateNvVarStore in the case lack
> of FlashNvVarStore, we should detect FlashNvVarStore before calls to
> PlatformValidateNvVarStore. If fail to detect FlashNvVarStore, we should
> return don't initialize the EmuVariableNvStore, otherwise calls to
> PlatformValidateNvVarStore and initialize the EmuVariableNvStore when
> succeed to validate the integrity of NvVarStore.
> 

While Secure Boot isn't supported at the moment for SEV-ES / SEV-SNP,
this will cause a boot failure for those types of VMs should it be
enabled.

SEV-ES results in:

Invalid MMIO opcode (AF)
ASSERT [SecMain] 
/root/kernels/ovmf-build-X64/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c(498): 
((BOOLEAN)(0==1))

while SEV-SNP just terminates with an error in Qemu.

I haven't looked into what the cause is at this time.

Thanks,
Tom

> Fixes: 4f173db8b45b ("OvmfPkg/PlatformInitLib: Add functions for 
> EmuVariableNvStore")
> Signed-off-by: hanliyang 
> ---
>  OvmfPkg/Library/PlatformInitLib/Platform.c| 47 +++
>  .../PlatformInitLib/PlatformInitLib.inf   |  1 +
>  2 files changed, 48 insertions(+)
> 
> diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c 
> b/OvmfPkg/Library/PlatformInitLib/Platform.c
> index f48bf16ae3..0a720a4c2c 100644
> --- a/OvmfPkg/Library/PlatformInitLib/Platform.c
> +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c
> @@ -895,6 +895,16 @@ PlatformReserveEmuVariableNvStore (
>return VariableStore;
>  }
>  
> +#define WRITE_BYTE_CMD   0x10
> +#define BLOCK_ERASE_CMD  0x20
> +#define CLEAR_STATUS_CMD 0x50
> +#define READ_STATUS_CMD  0x70
> +#define READ_DEVID_CMD   0x90
> +#define BLOCK_ERASE_CONFIRM_CMD  0xd0
> +#define READ_ARRAY_CMD   0xff
> +
> +#define CLEARED_ARRAY_STATUS  0x00
> +
>  /**
>   When OVMF is lauched with -bios parameter, UEFI variables will be
>   partially emulated, and non-volatile variables may lose their contents
> @@ -928,6 +938,43 @@ PlatformInitEmuVariableNvStore (
>Size = (UINT32)PcdGet32 (PcdFlashNvStorageVariableSize);
>ASSERT (Size < EmuVariableNvStoreSize);
>  
> +  //
> +  // If launch a VM without OvmfFlashNvStorage device, then we'll fail
> +  // to check the integrity of NvVarStore and trigger ASSERT (FALSE).
> +  // So, we should detect the OvmfFlashNvStorage before calls to
> +  // PlatformValidateNvVarStore(). If fail to detect OvmfFlashNvStorage,
> +  // we should return and don't initialize the EmuVariableNvStore,
> +  // otherwise calls to PlatformValidateNvVarStore() and initialize the
> +  // EmuVariableNvStore when succeed to check the integrity of
> +  // NvVarStore.
> +  //
> +  // This method to detect the OvmfFlashNvStorage here references
> +  // OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c.
> +  //
> +  volatile UINT8  *Ptr;
> +
> +  UINTN  BlockSize;
> +  UINTN  Offset;
> +  UINT8  ProbeUint8;
> +
> +  BlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
> +
> +  for (Offset = 0; Offset < BlockSize; Offset++) {
> +Ptr= Base + Offset;
> +ProbeUint8 = *Ptr;
> +if ((ProbeUint8 != CLEAR_STATUS_CMD) &&
> +(ProbeUint8 != READ_STATUS_CMD) &&
> +(ProbeUint8 != CLEARED_ARRAY_STATUS))
> +{
> +  break;
> +}
> +  }
> +
> +  if (Offset >= BlockSize) {
> +DEBUG ((DEBUG_INFO, "OvmfFlashNvStorage: Failed to find probe 
> location\n"));
> +return EFI_INVALID_PARAMETER;
> +  }
> +
>if (!PlatformValidateNvVarStore (Base, PcdGet32 (PcdCfvRawDataSize))) {
>  ASSERT (FALSE);
>  return EFI_INVALID_PARAMETER;
> diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf 
> b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
> index 21e6efa5e0..b7d5e63dcd 100644
> --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
> +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
> @@ -104,6 +104,7 @@
>gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize
>gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase
>gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
>  
>  [FeaturePcd]
>gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119935): 

Re: [edk2-devel] [PATCH ovmf v4 5/5] OvmfPkf: Enable AMD SEV-ES DebugVirtualization

2024-06-05 Thread Lendacky, Thomas via groups.io

On 6/4/24 21:09, Alexey Kardashevskiy wrote:

Write the feature bit into PcdConfidentialComputingGuestAttr
and enable DebugVirtualization in PEI, SEC, DXE.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Tom Lendacky 
Signed-off-by: Alexey Kardashevskiy 


Reviewed-by: Tom Lendacky 


---
Changes:
v4:
* s/DebugSwap/DebugVirtualization/g
* the feature is enabled here for all modes
---
  OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c |  6 +-
  OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c |  6 +-
  OvmfPkg/PlatformPei/AmdSev.c   | 13 
++---
  3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
index 7d823ad639f4..f381b9255bb7 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
@@ -154,5 +154,9 @@ MemEncryptSevEsDebugVirtualizationIsEnabled (
VOID
)
  {
-  return FALSE;
+  MSR_SEV_STATUS_REGISTER  Msr;
+
+  Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+  return Msr.Bits.DebugVirtualization ? TRUE : FALSE;
  }
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
index 33a326ac1571..946bed2ada13 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
@@ -154,7 +154,11 @@ MemEncryptSevEsDebugVirtualizationIsEnabled (
VOID
)
  {
-  return FALSE;
+  MSR_SEV_STATUS_REGISTER  Msr;
+
+  Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+  return Msr.Bits.DebugVirtualization ? TRUE : FALSE;
  }
  
  /**

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 88ca14507f5e..8562787035db 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -434,6 +434,7 @@ AmdSevInitialize (
)
  {
UINT64 EncryptionMask;
+  UINT64 CCGuestAttr;
RETURN_STATUS  PcdStatus;
  
//

@@ -517,13 +518,19 @@ AmdSevInitialize (
// technology is active.
//
if (MemEncryptSevSnpIsEnabled ()) {
-PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevSnp);
+CCGuestAttr = CCAttrAmdSevSnp;
} else if (MemEncryptSevEsIsEnabled ()) {
-PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevEs);
+CCGuestAttr = CCAttrAmdSevEs;
} else {
-PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSev);
+CCGuestAttr = CCAttrAmdSev;
}
  
+  if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) {

+CCGuestAttr |= CCAttrFeatureAmdSevEsDebugVirtualization;
+  }
+
+  PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCGuestAttr);
+
ASSERT_RETURN_ERROR (PcdStatus);
  }
  



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119484): https://edk2.groups.io/g/devel/message/119484
Mute This Topic: https://groups.io/mt/106496092/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH ovmf v4 4/5] UefiCpuPkg: Add AMD SEV-ES features support

2024-06-05 Thread Lendacky, Thomas via groups.io

On 6/4/24 21:09, Alexey Kardashevskiy wrote:

CONFIDENTIAL_COMPUTING_GUEST_ATTR is not a simple SEV level anymore
and includes a feature mask since the previous commit.

Fix AmdMemEncryptionAttrCheck to check the level and feature
correctly and add DebugVirtualization support.

Since the actual feature flag is not set yet, this should cause
no behavioural change.

Cc: Gerd Hoffmann 
Cc: Jiaxin Wu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Tom Lendacky 
Signed-off-by: Alexey Kardashevskiy 


Reviewed-by: Tom Lendacky 


---
  UefiCpuPkg/Library/MpInitLib/MpLib.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c 
b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index f97298887f96..444df2abdc1d 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -3196,19 +3196,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;
}



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119483): https://edk2.groups.io/g/devel/message/119483
Mute This Topic: https://groups.io/mt/106496089/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH ovmf v4 3/5] OvmfPkg: Add AMD SEV-ES DebugVirtualization feature support

2024-06-05 Thread Lendacky, Thomas via groups.io

On 6/4/24 21:09, Alexey Kardashevskiy wrote:

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
#VC for #DB or DB7 read/write occurs as this signals unwanted
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 
Cc: Tom Lendacky 
Signed-off-by: Alexey Kardashevskiy 


Reviewed-by: Tom Lendacky 


---
Changes:
v4:
* s/DebugSwap/DebugVirtualization/
---
  OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 
+
  OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 27 
+---
  OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c | 15 
+++
  OvmfPkg/Library/BaseMemEncryptSevLib/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 4fa9c0d70083..c5653539d8d8 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -166,6 +166,18 @@ MemEncryptSevGetEncryptionMask (
VOID
);
  
+/**

+  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.
  
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c

index 4aba0075b9e2..9947d663deae 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 41d1246a5b31..7d823ad639f4 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 27148c7e337a..33a326ac1571 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
@@ -142,6 +142,21 @@ 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 (

Re: [edk2-devel] [PATCH ovmf v4 1/5] MdePkg/Register/Amd: Define all bits from MSR_SEV_STATUS_REGISTER

2024-06-05 Thread Lendacky, Thomas via groups.io

On 6/4/24 21:09, Alexey Kardashevskiy wrote:

For now we need DebugSwap but others are likely to be needed too.

Cc: Tom Lendacky 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Signed-off-by: Alexey Kardashevskiy 


Reviewed-by: Tom Lendacky 


---
Changes:
v4:
* added more from April/2024 APM
---
  MdePkg/Include/Register/Amd/Fam17Msr.h | 95 +++-
  1 file changed, 91 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h 
b/MdePkg/Include/Register/Amd/Fam17Msr.h
index f2d5ccb39dc7..286b337f70fa 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -126,19 +126,106 @@ typedef union {
  ///
  /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
  ///
-UINT32SevBit: 1;
+UINT32SevBit  : 1;
  
  ///

  /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is 
enabled
  ///
-UINT32SevEsBit  : 1;
+UINT32SevEsBit: 1;
  
  ///

  /// [Bit 2] Secure Nested Paging (SevSnp) is enabled
  ///
-UINT32SevSnpBit : 1;
+UINT32SevSnpBit   : 1;
  
-UINT32Reserved2 : 29;

+///
+/// [Bit 3] Virtual TOM feature is enabled in SEV_FEATURES[1]
+///
+UINT32vTOM: 1;
+
+///
+/// [Bit 4] ReflectVC feature is enabled in SEV_FEATURES[2]
+///
+UINT32ReflectVC   : 1;
+
+///
+/// [Bit 5] Restricted Injection feature is enabled in SEV_FEATURES[3]
+///
+UINT32RestrictedInjection : 1;
+
+///
+/// [Bit 6] Alternate Injection feature is enabled in SEV_FEATURES[4]
+///
+UINT32AlternateInjection  : 1;
+
+///
+/// [Bit 7] Debug Virtualization feature is enabled in SEV_FEATURES[5]
+///
+UINT32DebugVirtualization : 1;
+
+///
+/// [Bit 8]  PreventHostIBS feature is enabled in SEV_FEATURES[6]
+///
+UINT32PreventHostIBS  : 1;
+
+///
+/// [Bit 9] BTB isolation feature is enabled in SEV_FEATURES[7]
+///
+UINT32SNPBTBIsolation : 1;
+
+///
+/// [Bit 10] VMPL SSS feature is enabled in SEV_FEATURES[8]
+///
+UINT32VmplSSS : 1;
+
+///
+/// [Bit 11] Secure TSC feature is enabled in SEV_FEATURES[9]
+///
+UINT32SecureTsc   : 1;
+
+///
+/// [Bit 12] VMGEXIT Parameter feature is enabled in SEV_FEATURES[10]
+///
+UINT32VmgexitParameter: 1;
+
+///
+/// [Bit 13] PMC Virtualization feature is enabled in SEV_FEATURES[11]
+///
+UINT32PmcVirtualization   : 1;
+
+///
+/// [Bit 14] IBS Virtualization feature is enabled in SEV_FEATURES[12]
+///
+UINT32IbsVirtualization   : 1;
+
+///
+/// [Bit 15]
+///
+UINT32Reserved1   : 1;
+
+///
+/// [Bit 16] VMSA Register Protection feature is enabled in 
SEV_FEATURES[14]
+///
+UINT32VmsaRegProt : 1;
+
+///
+/// [Bit 17] SMT Protection feature is enabled in SEV_FEATURES[15]
+///
+UINT32SmtProtection   : 1;
+///
+///
+/// [Bit 18] Secure AVIC feature is enabled in SEV_FEATURES[16]
+///
+UINT32SecureAVIC  : 1;
+
+UINT32Reserved2   : 4;
+
+///
+/// [Bit 23] IBPB on Entry feature is enabled in SEV_FEATURES[21]
+///
+UINT32IbpbOnEntry : 1;
+
+UINT32Reserved3   : 8;
} Bits;
///
/// All bit fields as a 32-bit value



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119481): https://edk2.groups.io/g/devel/message/119481
Mute This Topic: https://groups.io/mt/106496074/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 2/2] AmdSev: Halt on failed blob allocation

2024-05-30 Thread Lendacky, Thomas via groups.io

On 5/6/24 15:27, Tobin Feldman-Fitzthum wrote:

A malicious host may be able to undermine the fw_cfg
interface such that loading a blob fails.

In this case rather than continuing to the next boot
option, the blob verifier should halt.

For non-confidential guests, the error should be non-fatal.

Signed-off-by: Tobin Feldman-Fitzthum 
---
  .../BlobVerifierSevHashes.c | 17 -
  OvmfPkg/Include/Library/BlobVerifierLib.h   | 14 ++
  .../BlobVerifierLibNull/BlobVerifierNull.c  | 13 -
  .../QemuKernelLoaderFsDxe.c |  9 -
  4 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c 
b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
index ee8bca509a..c550518d73 100644
--- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
+++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
@@ -83,6 +83,7 @@ FindBlobEntryGuid (
@param[in] BlobName   The name of the blob
@param[in] BufThe data of the blob
@param[in] BufSizeThe size of the blob in bytes
+  @param[in] FetchStatusThe status of the previous blob fetch
  
@retval EFI_SUCCESS   The blob was verified successfully or was not

  found in the hash table.
@@ -94,13 +95,27 @@ EFIAPI
  VerifyBlob (
IN  CONST CHAR16  *BlobName,
IN  CONST VOID*Buf,
-  IN  UINT32BufSize
+  IN  UINT32BufSize,
+  IN  EFI_STATUSFetchStatus
)
  {
CONST GUID  *Guid;
INT32   Remaining;
HASH_TABLE  *Entry;
  
+  // Enter a dead loop if the fetching of this blob

+  // failed. This prevents a malicious host from
+  // circumventing the following checks.
+  if (EFI_ERROR (FetchStatus)) {
+DEBUG ((
+  DEBUG_ERROR,
+  "%a: Fetching blob failed.\n",
+  __func__
+  ));
+
+CpuDeadLoop ();
+  }
+
if ((mHashesTable == NULL) || (mHashesTableSize == 0)) {
  DEBUG ((
DEBUG_WARN,
diff --git a/OvmfPkg/Include/Library/BlobVerifierLib.h 
b/OvmfPkg/Include/Library/BlobVerifierLib.h
index 7e1af27574..efe26734b1 100644
--- a/OvmfPkg/Include/Library/BlobVerifierLib.h
+++ b/OvmfPkg/Include/Library/BlobVerifierLib.h
@@ -19,20 +19,26 @@
  /**
Verify blob from an external source.
  
+  If a non-secure configuration is detected this function will enter a

+  dead loop to prevent a boot.
+


Probably shouldn't specify this here as the VerifyBlob() that is not in 
AmdSev will not enter a dead loop.


Thanks,
Tom


@param[in] BlobName   The name of the blob
@param[in] BufThe data of the blob
@param[in] BufSizeThe size of the blob in bytes
+  @param[in] FetchStatusThe status of fetching this blob
  
-  @retval EFI_SUCCESS   The blob was verified successfully.

-  @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
-should be considered non-secure.
+  @retval EFI_SUCCESS   The blob was verified successfully or was not
+found in the hash table.
+  @retval EFI_ACCESS_DENIED Kernel hashes not supported but the boot can
+continue safely.
  **/
  EFI_STATUS
  EFIAPI
  VerifyBlob (
IN  CONST CHAR16  *BlobName,
IN  CONST VOID*Buf,
-  IN  UINT32BufSize
+  IN  UINT32BufSize,
+  IN  EFI_STATUSFetchStatus
);
  
  #endif

diff --git a/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c 
b/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c
index e817c3cc95..db5320571c 100644
--- a/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c
+++ b/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c
@@ -16,18 +16,21 @@
@param[in] BlobName   The name of the blob
@param[in] BufThe data of the blob
@param[in] BufSizeThe size of the blob in bytes
+  @param[in] FetchStatusThe status of the fetch of this blob
  
-  @retval EFI_SUCCESS   The blob was verified successfully.

-  @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
-should be considered non-secure.
+  @retval EFI_SUCCESS   The blob was verified successfully or was not
+found in the hash table.
+  @retval EFI_ACCESS_DENIED Kernel hashes not supported but the boot can
+continue safely.
  **/
  EFI_STATUS
  EFIAPI
  VerifyBlob (
IN  CONST CHAR16  *BlobName,
IN  CONST VOID*Buf,
-  IN  UINT32BufSize
+  IN  UINT32BufSize,
+  IN  EFI_STATUSFetchStatus
)
  {
-  return EFI_SUCCESS;
+  return FetchStatus;
  }
diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c 
b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
index 

Re: [edk2-devel] [PATCH 1/2] AmdSev: Rework Blob Verifier

2024-05-30 Thread Lendacky, Thomas via groups.io

On 5/6/24 15:27, Tobin Feldman-Fitzthum wrote:

The Blob Verifier checks boot artifacts against a hash table
injected by the hypervisor and measured by hardware.

Update the Blob Verifier to enter a dead loop if the artifacts
do not match.


There are some changes to messages from ERROR to WARN and the return is 
kept as EFI_ACCESS_DENIED, so it would be best to describe in the commit 
message what situations result in EFI_ACCES_DENIED vs dead loop.




Signed-off-by: Tobin Feldman-Fitzthum 
---
  .../BlobVerifierSevHashes.c   | 39 +++
  1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c 
b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
index 2e58794c3c..ee8bca509a 100644
--- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
+++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
@@ -77,13 +77,17 @@ FindBlobEntryGuid (
  /**
Verify blob from an external source.
  
+  If a non-secure configuration is detected this function will enter a

+  dead loop to prevent a boot.
+
@param[in] BlobName   The name of the blob
@param[in] BufThe data of the blob
@param[in] BufSizeThe size of the blob in bytes
  
-  @retval EFI_SUCCESS   The blob was verified successfully.

-  @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
-should be considered non-secure.
+  @retval EFI_SUCCESS   The blob was verified successfully or was not
+found in the hash table.
+  @retval EFI_ACCESS_DENIED Kernel hashes not supported, but the boot
+can continue safely.
  **/
  EFI_STATUS
  EFIAPI
@@ -99,8 +103,8 @@ VerifyBlob (
  
if ((mHashesTable == NULL) || (mHashesTableSize == 0)) {

  DEBUG ((
-  DEBUG_ERROR,
-  "%a: Verifier called but no hashes table discoverd in MEMFD\n",
+  DEBUG_WARN,
+  "%a: No hashes table discovered in MEMFD\n",


Technically, this should really just change the ERROR to WARN without 
changing the message text.



__func__
));
  return EFI_ACCESS_DENIED;
@@ -114,7 +118,8 @@ VerifyBlob (
__func__,
BlobName
));
-return EFI_ACCESS_DENIED;
+
+CpuDeadLoop ();
}
  
//

@@ -136,10 +141,22 @@ VerifyBlob (
  
  DEBUG ((DEBUG_INFO, "%a: Found GUID %g in table\n", __func__, Guid));
  
+if (BufSize == 0) {

+  DEBUG ((
+DEBUG_ERROR,
+"%a: Blob Specified in Hash Table was not Provided",
+__func__,
+EntrySize,
+SHA256_DIGEST_SIZE


Looks like there's no substitution spots in the message for these last 
two parameters.


Thanks,
Tom


+));
+
+  CpuDeadLoop ();
+}
+
  EntrySize = Entry->Len - sizeof Entry->Guid - sizeof Entry->Len;
  if (EntrySize != SHA256_DIGEST_SIZE) {
DEBUG ((
-DEBUG_ERROR,
+DEBUG_WARN,
  "%a: Hash has the wrong size %d != %d\n",
  __func__,
  EntrySize,
@@ -170,18 +187,24 @@ VerifyBlob (
  __func__,
  BlobName
  ));
+
+  CpuDeadLoop ();
  }
  
  return Status;

}
  
+  //

+  // If the GUID is not in the hash table, execution can still continue.
+  // This blob will not be measured, but at least one blob must be.
+  //
DEBUG ((
  DEBUG_ERROR,
  "%a: Hash GUID %g not found in table\n",
  __func__,
  Guid
  ));
-  return EFI_ACCESS_DENIED;
+  return EFI_SUCCESS;
  }
  
  /**



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119397): https://edk2.groups.io/g/devel/message/119397
Mute This Topic: https://groups.io/mt/105977014/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH ovmf v3 4/5] UefiCpuPkg: Add AMD SEV-ES features support

2024-05-20 Thread Lendacky, Thomas via groups.io

On 5/2/24 09:34, Alexey Kardashevskiy wrote:

CONFIDENTIAL_COMPUTING_GUEST_ATTR is not a simple SEV level anymore
and includes a feature mask since a previous commit.

This fixes AmdMemEncryptionAttrCheck to check the level and feature
correctly and adds DebugSwap support.

Since the actual feature flag is not set yet, this should cause
no behavioural change.

Cc: Gerd Hoffmann 
Cc: Jiaxin Wu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Tom Lendacky 
Signed-off-by: Alexey Kardashevskiy 


Reviewed-by: Tom Lendacky 


---
  UefiCpuPkg/Library/MpInitLib/MpLib.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c 
b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index d7244565029d..52fddfb7e571 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -3178,19 +3178,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 CCAttrFeatureAmdSevDebugSwap:
+  return !!(CurrentAttr & CCAttrFeatureAmdSevDebugSwap);
  default:
return FALSE;
}



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119088): https://edk2.groups.io/g/devel/message/119088
Mute This Topic: https://groups.io/mt/105863831/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH ovmf v3 3/5] OvmfPkg: Add AMD SEV-ES DebugSwap feature support

2024-05-20 Thread Lendacky, Thomas via groups.io

On 5/2/24 09:34, Alexey Kardashevskiy wrote:

The SEV-ES DebugSwap feature enables type B swaping of debug registers
on #VMEXIT and makes #DB and DR7 intercepts unnecessary and unwanted.

When DebugSwap is enabled, this stops booting if #VC for #DB or
DB7 read/write occurs as this signals unwanted interaction from the HV.

This adds new API which uses SEV-ES working area in PEI and SEC.

This does not change the existing behavour for DXE just yet but soon.


This changes the SEC/PEI behavior while not changing DXE, which means 
two different behaviors. I wonder if the SEC and PEI changes that access 
the MSR value, should be part of the final patch that enables it for all 
stages. And in this patch, just have the SEC and PEI versions of 
MemEncryptSevEsDebugSwapIsEnabled() return FALSE for now.


Thanks,
Tom



Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Tom Lendacky 
Signed-off-by: Alexey Kardashevskiy 
---
  OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 
+
  OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 27 
+---
  OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c | 19 
++
  OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c | 19 
++
  OvmfPkg/Library/CcExitLib/CcExitVcHandler.c|  8 ++
  5 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h 
b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 4fa9c0d70083..0fa86aecc38c 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -166,6 +166,18 @@ MemEncryptSevGetEncryptionMask (
VOID
);
  
+/**

+  Returns a boolean to indicate whether DebugSwap is enabled.
+
+  @retval TRUE   DebugSwap is enabled
+  @retval FALSE  DebugSwap is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugSwapIsEnabled (
+  VOID
+  );
+
  /**
Returns the encryption state of the specified virtual address range.
  
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c

index 4aba0075b9e2..ebc4c9bb5d06 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 CCAttrFeatureAmdSevDebugSwap:
+  return !!(CurrentAttr & CCAttrFeatureAmdSevDebugSwap);
  default:
return FALSE;
}
@@ -159,3 +165,18 @@ MemEncryptSevGetEncryptionMask (
  
return mSevEncryptionMask;

  }
+
+/**
+  Returns a boolean to indicate whether DebugSwap is enabled.
+
+  @retval TRUE   DebugSwap is enabled
+  @retval FALSE  DebugSwap is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugSwapIsEnabled (
+  VOID
+  )
+{
+  return ConfidentialComputingGuestHas (CCAttrFeatureAmdSevDebugSwap);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
index 41d1246a5b31..e2ebc8afcaee 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
@@ -141,3 +141,22 @@ MemEncryptSevGetEncryptionMask (
  
return SevEsWorkArea->EncryptionMask;

  }
+
+/**
+  Returns a boolean to indicate whether DebugSwap is enabled.
+
+  @retval TRUE   DebugSwap is enabled
+  @retval FALSE  DebugSwap is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugSwapIsEnabled (
+  VOID
+  )
+{
+  MSR_SEV_STATUS_REGISTER  Msr;
+
+  Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+  return Msr.Bits.DebugSwap ? TRUE : FALSE;
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
index 27148c7e337a..0e82dc85b299 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
@@ -142,6 +142,25 @@ MemEncryptSevGetEncryptionMask (
return SevEsWorkArea->EncryptionMask;
 

Re: [edk2-devel] [PATCH ovmf v3 2/5] MdePkg: Add AMD SEV features to PcdConfidentialComputingGuestAttr

2024-05-20 Thread Lendacky, Thomas via groups.io

On 5/2/24 09:34, Alexey Kardashevskiy wrote:

PcdConfidentialComputingGuestAttr so far only contained an SEV mode bit
but there are more other features which do not translate to levels
such as DebugSwap or SecureTsc.

This adds the features mask and the DebugSwap feature bit to a PCD.

Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Cc: Tom Lendacky 
Signed-off-by: Alexey Kardashevskiy 


One nit below, otherwise:

Reviewed-by: Tom Lendacky 


---
Changes:
v2:
* expanded features mask
* added type mask
---
  MdePkg/Include/ConfidentialComputingGuestAttr.h | 15 +--
  1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/ConfidentialComputingGuestAttr.h 
b/MdePkg/Include/ConfidentialComputingGuestAttr.h
index 44e6df800207..c3a3dfb393f0 100644
--- a/MdePkg/Include/ConfidentialComputingGuestAttr.h
+++ b/MdePkg/Include/ConfidentialComputingGuestAttr.h
@@ -29,9 +29,20 @@ typedef enum {
  
/* The guest is running with Intel TDX memory encryption enabled. */

CCAttrIntelTdx = 0x200,
+
+  CCAttrTypeMask = 0x,
+
+  /* Features */
+
+  /* The AMD SEV-ES DebugSwap feature is enabled in SEV_STATUS */
+  CCAttrFeatureAmdSevDebugSwap = 0x0001,


Should this be CCAttrFeatureAmdSevEsDebugSwap? Otherwise, maybe just 
make it CCAttrFeatureAmdDebugSwap.


Thanks,
Tom


+
+  CCAttrFeatureMask = 0x,
  } CONFIDENTIAL_COMPUTING_GUEST_ATTR;
  
-#define CC_GUEST_IS_TDX(x)  ((x) == CCAttrIntelTdx)

-#define CC_GUEST_IS_SEV(x)  ((x) == CCAttrAmdSev || (x) == CCAttrAmdSevEs || 
(x) == CCAttrAmdSevSnp)
+#define _CC_GUEST_IS_TDX(x)  ((x) == CCAttrIntelTdx)
+#define CC_GUEST_IS_TDX(x)   _CC_GUEST_IS_TDX((x) & CCAttrTypeMask)
+#define _CC_GUEST_IS_SEV(x)  ((x) == CCAttrAmdSev || (x) == CCAttrAmdSevEs || 
(x) == CCAttrAmdSevSnp)
+#define CC_GUEST_IS_SEV(x)   _CC_GUEST_IS_SEV((x) & CCAttrTypeMask)
  
  #endif



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119086): https://edk2.groups.io/g/devel/message/119086
Mute This Topic: https://groups.io/mt/105863820/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH ovmf v3 1/5] MdePkg/Register/Amd: Define all bits from MSR_SEV_STATUS_REGISTER

2024-05-20 Thread Lendacky, Thomas via groups.io

On 5/2/24 09:34, Alexey Kardashevskiy wrote:

For now we need DebugSwap but others are likely to be needed too.

Cc: Tom Lendacky 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Signed-off-by: Alexey Kardashevskiy 


A recent APM has defined a few more and has slightly different naming 
(see below). If you have to submit another version it might be good to 
update them. Otherwise:


Reviewed-by: Tom Lendacky 


---
  MdePkg/Include/Register/Amd/Fam17Msr.h | 63 ++--
  1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h 
b/MdePkg/Include/Register/Amd/Fam17Msr.h
index f2d5ccb39dc7..bce51a66517f 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -126,19 +126,74 @@ typedef union {
  ///
  /// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
  ///
-UINT32SevBit: 1;
+UINT32SevBit  : 1;
  
  ///

  /// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is 
enabled
  ///
-UINT32SevEsBit  : 1;
+UINT32SevEsBit: 1;
  
  ///

  /// [Bit 2] Secure Nested Paging (SevSnp) is enabled
  ///
-UINT32SevSnpBit : 1;
+UINT32SevSnpBit   : 1;
  
-UINT32Reserved2 : 29;

+///
+/// [Bit 3] The guest was run with the Virtual TOM feature enabled in 
SEV_FEATURES[1]
+///
+UINT32vTOM_Enabled: 1;


The APM has this as vTOM and the PPR as VirtualTOM, so can probably 
remove the _Enabled.



+
+///
+/// [Bit 4] The guest was run with the ReflectVC feature enabled in 
SEV_FEATURES[2]
+///
+UINT32ReflectVC   : 1;
+
+///
+/// [Bit 5] The guest was run with the Restricted Injection feature 
enabled in SEV_FEATURES[3]
+///
+UINT32RestrictedInjection : 1;
+
+///
+/// [Bit 6] The guest was run with the Alternate Injection feature enabled 
in SEV_FEATURES[4]
+///
+UINT32AlternateInjection  : 1;
+
+///
+/// [Bit 7] This guest was run with debug register swapping enabled in 
SEV_FEATURES[5]
+///
+UINT32DebugSwap   : 1;


The APM has this as DebugVirtualization and the PPR as DebugSwapSupport.


+
+///
+/// [Bit 8]  This guest was run with the PreventHostIBS feature enabled in 
SEV_FEATURES[6]
+///
+UINT32PreventHostIBS  : 1;
+
+///
+/// [Bit 9] The guest was run with the BTB isolation feature enabled in 
SEV_FEATURES[7]
+///
+UINT32SNPBTBIsolation : 1;


The APM has this as BTBIsolation, while the PPR has it as you do.


+
+///
+/// [Bit 10]
+///
+UINT32Reserved0   : 1;
+
+///
+/// [Bit 11] The guest was run with the Secure TSC feature enabled in 
SEV_FEATURES[9]
+///
+UINT32SecureTsc   : 1;
+
+///
+/// [Bits 12 13 14 15]
+///
+UINT32Reserved1   : 4;
+
+///
+/// [Bit 16] The guest was run with the VMSA Register Protection feature 
enabled in SEV_FEATURES[14]
+///
+UINT32VmsaRegProt_Enabled : 1;


The APM has this VmsaRegProt, so can probably drop the _Enabled.


+
+UINT32Reserved2   : 15;
} Bits;
///
/// All bit fields as a 32-bit value



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119085): https://edk2.groups.io/g/devel/message/119085
Mute This Topic: https://groups.io/mt/105863816/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v3 00/13] Add SmmRelocationLib

2024-04-26 Thread Lendacky, Thomas via groups.io

On 4/25/24 01:58, Gerd Hoffmann wrote:

   Hi,


That means the SMMRevId is 0_xx64h for AMD64 processor. But I am not
sure what the value is for AMD32 processor. Maybe 0 according to the
OVMF logic.


The smm emulation in the linux kernel uses 0 and 0x64.


But, I am very suspicious about the logic in AMD's version as below:
--- AMD's version
   SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT;

   LMAValue = (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA;
   if (LMAValue) {
 SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT;
   }
---
The above logic detects the current CPU mode and 64bit save state area layout 
is used if it's running in 64bit.



But if a AMD64 CPU runs in 32bit mode, the above logic causes the
32bit save state area layout is used. It's not right!  The save state
area layout does not depend on the CPU running mode, but whether it's
a legacy CPU or a 64-capable CPU.


Well, that is not entirely clear to me.  Could it be 64-bit processors
support both 32-bit and 64-bit format, for backward compatibility
reasons?

So OvmfPkgIa32 builds could use the 32-bit format, OvmfPkgX64 builds use
the 64-bit format, everything works fine?

The tricky corner case is OvmfPkgIa32X64, where (after applying this
series) 32-bit PEI should setup things for 64-bit SMM/DXE, and checking
the current processor mode will not give use the result we need.


Jiaxin, I agree that the confusion should be cleaned up by AMD
experts. Let's not change any existing behavior.


Agree.  Tom?


I don't have a lot of experience with SMM. I believe Paolo first ported 
over the support into OVMF and might have more insight?


I'll try to take a look at it when I can, but maybe @Abner or @Abdul might 
have more understanding of SMM with which they can comment.


Thanks,
Tom



take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118340): https://edk2.groups.io/g/devel/message/118340
Mute This Topic: https://groups.io/mt/105593568/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH] OvmfPkg: Don't make APIC MMIO accesses with encryption bit set

2024-04-24 Thread Lendacky, Thomas via groups.io

On 4/24/24 09:45, Gerd Hoffmann wrote:

   Hi,


Ideally CpuPageTableLib should be used for this.


CpuPageTableLib will need to be modified in order for it to be used at this
(Sec) stage. In order to work in Sec - either the caller will have to supply
a list of pages that can be used if pagetable entries need to be allocated
for splits


I don't think so.  PageTableMap() has the 'Buffer' parameter for passing
in page table memory.  And the patch reserves a page in MEMFD.  Handing
that page over to PageTableMap() should work just fine, no?


Oh, I thought the library allocated the pages, my bad. Mike and I will 
take a look at that.


Thanks,
Tom



take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118223): https://edk2.groups.io/g/devel/message/118223
Mute This Topic: https://groups.io/mt/105698125/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH] OvmfPkg: Don't make APIC MMIO accesses with encryption bit set

2024-04-24 Thread Lendacky, Thomas via groups.io

On 4/24/24 06:54, Gerd Hoffmann wrote:

On Tue, Apr 23, 2024 at 03:59:58PM -0500, Michael Roth wrote:

For the most part, OVMF will clear the encryption bit for MMIO regions,
but there is currently one known exception during SEC when the APIC
base address is accessed via MMIO with the encryption bit set for
SEV-ES/SEV-SNP guests.


what exactly accesses the lapic that early?


InitializedApicTimer() in OvmfPkg/Sec/SecMain.c




+/**
+  Map known MMIO regions unencrypted if SEV-ES is active.
+
+  During early booting, page table entries default to having the encryption bit
+  set for SEV-ES/SEV-SNP guests. In cases where there is MMIO to an address, 
the
+  encryption bit should be cleared. Clear it here for any known MMIO accesses
+  during SEC, which is currently just the APIC base address.
+
+**/
+VOID
+SecMapApicBaseUnencrypted (
+  VOID
+  )
+{
+  PAGE_MAP_AND_DIRECTORY_POINTER  *Level4Entry;
+  PAGE_MAP_AND_DIRECTORY_POINTER  *Level3Entry;
+  PAGE_MAP_AND_DIRECTORY_POINTER  *Level2Entry;
+  PAGE_TABLE_4K_ENTRY *Level1Entry;
+  SEC_SEV_ES_WORK_AREA*SevEsWorkArea;
+  PHYSICAL_ADDRESSCr3;
+  UINT64  ApicAddress;
+  UINT64  PgTableMask;
+  UINT32  Level1Page;
+  UINT64  Level1Address;
+  UINT64  Level1Flags;
+  UINTN   PteIndex;
+
+  if (!SevEsIsEnabled ()) {
+return;
+  }


That is incompatible with 5-level paging.  The current reset vector will
never turn on 5-level paging in case SEV is active because we have more
incompatibilities elsewhere (BaseMemEncryptSevLib IIRC).  But still,
it's moving things into the wrong direction ...


Agreed. SEV needs to clean up the pagetable manipulation in general in 
order to support 5-level paging and remove redundant code. That will be 
a patch series in itself.


But without this modification, the SNP support no longer works with the 
KVM/gmem support that will be upstream. This change gets OVMF SNP 
support working again.




Ideally CpuPageTableLib should be used for this.


CpuPageTableLib will need to be modified in order for it to be used at 
this (Sec) stage. In order to work in Sec - either the caller will have 
to supply a list of pages that can be used if pagetable entries need to 
be allocated for splits or new entries or by providing some kind of SEC 
pagetable allocation pool.


So it will take significant work to get SEV support updated to using 
CpuPageTableLib and that's why with this single patch we can get OVMF 
SNP support working again.


Thanks,
Tom



take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118215): https://edk2.groups.io/g/devel/message/118215
Mute This Topic: https://groups.io/mt/105698125/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 7/7] OvmfPkg: Use newly defined Unaccepted Memory Type

2024-04-22 Thread Lendacky, Thomas via groups.io

On 4/19/24 16:46, Sachin Ganesh wrote:

EFI_RESOURCE_MEMORY_UNACCEPTED has been officially defined in the PI
1.8 specification. So all temporary solutions have been replaced with
the actual definition.

Cc: Felix Polyudov 
Cc: Dhanaraj V 
Cc: Jiewen Yao 
Cc: Liming Gao 
Signed-off-by: Sachin Ganesh 


Reviewed-by: Tom Lendacky 


---
  OvmfPkg/AmdSevDxe/AmdSevDxe.c| 4 ++--
  OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c | 8 
  OvmfPkg/Library/PeilessStartupLib/Hob.c  | 4 ++--
  OvmfPkg/Library/PlatformInitLib/IntelTdx.c   | 8 
  OvmfPkg/PlatformPei/AmdSev.c | 4 ++--
  5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
index db3675ae86..d497a343d3 100644
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
@@ -20,7 +20,7 @@
  #include 

  #include 

  #include 

-#include 

+#include 

  #include 

  #include 

  #include 

@@ -119,7 +119,7 @@ AcceptAllMemory (
  CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *Desc;



  Desc = [Index];

-if (Desc->GcdMemoryType != EFI_GCD_MEMORY_TYPE_UNACCEPTED) {

+if (Desc->GcdMemoryType != EfiGcdMemoryTypeUnaccepted) {

continue;

  }



diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c 
b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
index 3372cee2f7..b6085eab44 100644
--- a/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
+++ b/OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
@@ -19,7 +19,7 @@
  #include 

  #include 

  #include 

-#include 

+#include 

  #include 

  #include 

  #include 

@@ -351,7 +351,7 @@ AcceptMemoryForAPsStack (
  if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", 
Hob.ResourceDescriptor->ResourceType));



-  if (Hob.ResourceDescriptor->ResourceType == 
BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {

+  if (Hob.ResourceDescriptor->ResourceType == 
EFI_RESOURCE_MEMORY_UNACCEPTED) {

  ResourceLength = Hob.ResourceDescriptor->ResourceLength;

  PhysicalStart  = Hob.ResourceDescriptor->PhysicalStart;

  PhysicalEnd= PhysicalStart + ResourceLength;

@@ -427,7 +427,7 @@ AcceptMemory (
//

while (!END_OF_HOB_LIST (Hob)) {

  if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

-  if (Hob.ResourceDescriptor->ResourceType == 
BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {

+  if (Hob.ResourceDescriptor->ResourceType == 
EFI_RESOURCE_MEMORY_UNACCEPTED) {

  PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;

  PhysicalEnd   = PhysicalStart + 
Hob.ResourceDescriptor->ResourceLength;



@@ -563,7 +563,7 @@ ValidateHobList (
  EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,

  EFI_RESOURCE_MEMORY_RESERVED,

  EFI_RESOURCE_IO_RESERVED,

-BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED

+EFI_RESOURCE_MEMORY_UNACCEPTED

};



if (VmmHobList == NULL) {

diff --git a/OvmfPkg/Library/PeilessStartupLib/Hob.c 
b/OvmfPkg/Library/PeilessStartupLib/Hob.c
index 318b74c95d..725927da73 100644
--- a/OvmfPkg/Library/PeilessStartupLib/Hob.c
+++ b/OvmfPkg/Library/PeilessStartupLib/Hob.c
@@ -20,7 +20,7 @@
  #include 

  #include 

  #include 

-#include 

+#include 

  #include "PeilessStartupInternal.h"



  /**

@@ -92,7 +92,7 @@ ConstructFwHobList (
//

while (!END_OF_HOB_LIST (Hob)) {

  if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {

-  if (Hob.ResourceDescriptor->ResourceType == 
BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {

+  if (Hob.ResourceDescriptor->ResourceType == 
EFI_RESOURCE_MEMORY_UNACCEPTED) {

  PhysicalEnd= Hob.ResourceDescriptor->PhysicalStart + 
Hob.ResourceDescriptor->ResourceLength;

  ResourceLength = Hob.ResourceDescriptor->ResourceLength;



diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c 
b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index ada8592ddd..e561cee30b 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -17,7 +17,7 @@
  #include 

  #include 

  #include 

-#include 

+#include 

  #include 

  #include 



@@ -40,9 +40,9 @@ BuildResourceDescriptorHobForUnacceptedMemory (
EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute;

UINT64   MaxAcceptedMemoryAddress;



-  ASSERT (Hob->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED);

+  ASSERT (Hob->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED);



-  ResourceType  = BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED;

+  ResourceType  = EFI_RESOURCE_MEMORY_UNACCEPTED;

ResourceAttribute = Hob->ResourceAttribute;

PhysicalStart = Hob->PhysicalStart;

ResourceLength= Hob->ResourceLength;

@@ -104,7 +104,7 @@ TransferTdxHobList (
  ResourceType  = Hob.ResourceDescriptor->ResourceType;

  ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;



-if (ResourceType == 

Re: [edk2-devel] [PATCH v2] OvmfPkg: Harden #VC instruction emulation somewhat (CVE-2024-25742)

2024-04-22 Thread Lendacky, Thomas via groups.io

On 4/19/24 13:21, Adam Dunlap via groups.io wrote:

Ensure that when a #VC exception happens, the instruction at the
instruction pointer matches the instruction that is expected given the
error code. This is to mitigate the ahoi WeSee attack [1] that could
allow hypervisors to breach integrity and confidentiality of the
firmware by maliciously injecting interrupts. This change is a
translated version of a linux patch e3ef461af35a ("x86/sev: Harden #VC
instruction emulation somewhat")

[1] https://ahoi-attacks.github.io/wesee/

Cc: Borislav Petkov (AMD) 
Cc: Tom Lendacky 
Signed-off-by: Adam Dunlap 


Reviewed-by: Tom Lendacky 


---

Patch changelog:
V1 -> V2: Added the MWAITX/MONITORX opcodes. Added the opcode for INVD.
Added a comment to explain skipping the exit handling if the opcode does
not match.

  OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 184 ++--
  1 file changed, 173 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c 
b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
index 0fc30f7bc4..31587586fe 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
@@ -532,8 +532,6 @@ MwaitExit (
IN CC_INSTRUCTION_DATA *InstructionData
)
  {
-  CcDecodeModRm (Regs, InstructionData);
-
Ghcb->SaveArea.Rax = Regs->Rax;
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
Ghcb->SaveArea.Rcx = Regs->Rcx;
@@ -564,8 +562,6 @@ MonitorExit (
IN CC_INSTRUCTION_DATA *InstructionData
)
  {
-  CcDecodeModRm (Regs, InstructionData);
-
Ghcb->SaveArea.Rax = Regs->Rax;  // Identity mapped, so VA = PA
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
Ghcb->SaveArea.Rcx = Regs->Rcx;
@@ -670,8 +666,6 @@ VmmCallExit (
  {
UINT64  Status;
  
-  CcDecodeModRm (Regs, InstructionData);

-
Ghcb->SaveArea.Rax = Regs->Rax;
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
Ghcb->SaveArea.Cpl = (UINT8)(Regs->Cs & 0x3);
@@ -1603,8 +1597,6 @@ Dr7WriteExit (
Ext   = >Ext;
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
  
-  CcDecodeModRm (Regs, InstructionData);

-
//
// MOV DRn always treats MOD == 3 no matter how encoded
//
@@ -1655,8 +1647,6 @@ Dr7ReadExit (
Ext   = >Ext;
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
  
-  CcDecodeModRm (Regs, InstructionData);

-
//
// MOV DRn always treats MOD == 3 no matter how encoded
//
@@ -1671,6 +1661,170 @@ Dr7ReadExit (
return 0;
  }
  
+/**

+  Check that the opcode matches the exit code for a #VC.
+
+  Each exit code should only be raised while executing certain instructions.
+  Verify that rIP points to a correct instruction based on the exit code to
+  protect against maliciously injected interrupts via the hypervisor. If it 
does
+  not, report an unsupported event to the hypervisor.
+
+  Decodes the ModRm byte into InstructionData if necessary.
+
+  @param[in, out] Ghcb Pointer to the Guest-Hypervisor 
Communication
+   Block
+  @param[in, out] Regs x64 processor context
+  @param[in, out] InstructionData  Instruction parsing context
+  @param[in]  ExitCode Exit code given by #VC.
+
+  @retval 0No problems detected.
+  @return  New exception value to propagate
+
+
+**/
+STATIC
+UINT64
+VcCheckOpcodeBytes (
+  IN OUT GHCB*Ghcb,
+  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
+  IN OUT CC_INSTRUCTION_DATA *InstructionData,
+  IN UINT64  ExitCode
+  )
+{
+  UINT8  OpCode;
+
+  //
+  // Expected opcodes are either 1 or 2 bytes. If they are 2 bytes, they always
+  // start with TWO_BYTE_OPCODE_ESCAPE (0x0f), so skip over that.
+  //
+  OpCode = *(InstructionData->OpCodes);
+  if (OpCode == TWO_BYTE_OPCODE_ESCAPE) {
+OpCode = *(InstructionData->OpCodes + 1);
+  }
+
+  switch (ExitCode) {
+case SVM_EXIT_IOIO_PROT:
+case SVM_EXIT_NPF:
+  /* handled separately */
+  return 0;
+
+case SVM_EXIT_CPUID:
+  if (OpCode == 0xa2) {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_INVD:
+  if (OpCode == 0x08) {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_MONITOR:
+  CcDecodeModRm (Regs, InstructionData);
+
+  if ((OpCode == 0x01) &&
+  (  (InstructionData->ModRm.Uint8 == 0xc8)   /* MONITOR */
+  || (InstructionData->ModRm.Uint8 == 0xfa))) /* MONITORX */
+  {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_MWAIT:
+  CcDecodeModRm (Regs, InstructionData);
+
+  if ((OpCode == 0x01) &&
+  (  (InstructionData->ModRm.Uint8 == 0xc9)   /* MWAIT */
+  || (InstructionData->ModRm.Uint8 == 0xfb))) /* MWAITX */
+  {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_MSR:
+  /* RDMSR */
+  if ((OpCode == 0x32) ||
+  /* WRMSR */
+  (OpCode == 0x30))
+  {
+return 0;
+  }
+
+  

Re: [edk2-devel] [PATCH] OvmfPkg: Harden #VC instruction emulation somewhat (CVE-2024-25742)

2024-04-19 Thread Lendacky, Thomas via groups.io

On 4/17/24 11:54, Adam Dunlap wrote:

Ensure that when a #VC exception happens, the instruction at the
instruction pointer matches the instruction that is expected given the
error code. This is to mitigate the ahoi WeSee attack [1] that could
allow hypervisors to breach integrity and confidentiality of the
firmware by maliciously injecting interrupts. This change is a
translated version of a linux patch e3ef461af35a ("x86/sev: Harden #VC
instruction emulation somewhat")

[1] https://ahoi-attacks.github.io/wesee/

Cc: Borislav Petkov (AMD) 
Cc: Tom Lendacky 
Signed-off-by: Adam Dunlap 
---
  OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 171 ++--
  1 file changed, 160 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c 
b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
index 0fc30f7bc4..bd3e9f304a 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
@@ -532,8 +532,6 @@ MwaitExit (
IN CC_INSTRUCTION_DATA *InstructionData
)
  {
-  CcDecodeModRm (Regs, InstructionData);
-
Ghcb->SaveArea.Rax = Regs->Rax;
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
Ghcb->SaveArea.Rcx = Regs->Rcx;
@@ -564,8 +562,6 @@ MonitorExit (
IN CC_INSTRUCTION_DATA *InstructionData
)
  {
-  CcDecodeModRm (Regs, InstructionData);
-
Ghcb->SaveArea.Rax = Regs->Rax;  // Identity mapped, so VA = PA
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
Ghcb->SaveArea.Rcx = Regs->Rcx;
@@ -670,8 +666,6 @@ VmmCallExit (
  {
UINT64  Status;
  
-  CcDecodeModRm (Regs, InstructionData);

-
Ghcb->SaveArea.Rax = Regs->Rax;
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
Ghcb->SaveArea.Cpl = (UINT8)(Regs->Cs & 0x3);
@@ -1603,8 +1597,6 @@ Dr7WriteExit (
Ext   = >Ext;
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
  
-  CcDecodeModRm (Regs, InstructionData);

-
//
// MOV DRn always treats MOD == 3 no matter how encoded
//
@@ -1655,8 +1647,6 @@ Dr7ReadExit (
Ext   = >Ext;
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
  
-  CcDecodeModRm (Regs, InstructionData);

-
//
// MOV DRn always treats MOD == 3 no matter how encoded
//
@@ -1671,6 +1661,160 @@ Dr7ReadExit (
return 0;
  }
  
+/**

+  Check that the opcode matches the exit code for a #VC.
+
+  Each exit code should only be raised while executing certain instructions.
+  Verify that rIP points to a correct instruction based on the exit code to
+  protect against maliciously injected interrupts via the hypervisor. If it 
does
+  not, report an unsupported event to the hypervisor.
+
+  Decodes the ModRm byte into InstructionData if necessary.
+
+  @param[in, out] Ghcb Pointer to the Guest-Hypervisor 
Communication
+   Block
+  @param[in, out] Regs x64 processor context
+  @param[in, out] InstructionData  Instruction parsing context
+  @param[in]  ExitCode Exit code given by #VC.
+
+  @retval 0No problems detected.
+  @return  New exception value to propagate
+
+
+**/
+STATIC
+UINT64
+VcCheckOpcodeBytes (
+  IN OUT GHCB*Ghcb,
+  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
+  IN OUT CC_INSTRUCTION_DATA *InstructionData,
+  IN UINT64  ExitCode
+  )
+{
+  UINT8  OpCode;
+
+  //
+  // Expected opcodes are either 1 or 2 bytes. If they are 2 bytes, they always
+  // start with TWO_BYTE_OPCODE_ESCAPE (0x0f), so skip over that.
+  //
+  OpCode = *(InstructionData->OpCodes);
+  if (OpCode == TWO_BYTE_OPCODE_ESCAPE) {
+OpCode = *(InstructionData->OpCodes + 1);
+  }
+
+  switch (ExitCode) {
+case SVM_EXIT_IOIO_PROT:
+case SVM_EXIT_NPF:
+  /* handled separately */
+  return 0;
+
+case SVM_EXIT_CPUID:
+  if (OpCode == 0xa2) {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_INVD:
+  break;


This changes the current behavior today, but I'm ok with that.


+
+case SVM_EXIT_MONITOR:
+  CcDecodeModRm (Regs, InstructionData);
+
+  if ((OpCode == 0x01) && (InstructionData->ModRm.Uint8 == 0xc8)) {


This should also handle the MONITORX opcode (hmmm... I need to send a 
patch to the kernel).



+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_MWAIT:
+  CcDecodeModRm (Regs, InstructionData);
+
+  if ((OpCode == 0x01) && (InstructionData->ModRm.Uint8 == 0xc9)) {


Same here for MWAITX.

Thanks,
Tom


+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_MSR:
+  /* RDMSR */
+  if ((OpCode == 0x32) ||
+  /* WRMSR */
+  (OpCode == 0x30))
+  {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_RDPMC:
+  if (OpCode == 0x33) {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_RDTSC:
+  if (OpCode == 0x31) {
+return 0;
+  }
+
+  break;
+
+case SVM_EXIT_RDTSCP:
+  CcDecodeModRm (Regs, InstructionData);
+
+ 

Re: [edk2-devel] [PATCH] OvmfPkg: Harden #VC instruction emulation somewhat (CVE-2024-25742)

2024-04-19 Thread Lendacky, Thomas via groups.io

On 4/18/24 07:15, Gerd Hoffmann via groups.io wrote:

On Wed, Apr 17, 2024 at 09:54:00AM -0700, Adam Dunlap via groups.io wrote:

Ensure that when a #VC exception happens, the instruction at the
instruction pointer matches the instruction that is expected given the
error code. This is to mitigate the ahoi WeSee attack [1] that could
allow hypervisors to breach integrity and confidentiality of the
firmware by maliciously injecting interrupts. This change is a
translated version of a linux patch e3ef461af35a ("x86/sev: Harden #VC
instruction emulation somewhat")



+**/
+STATIC
+UINT64
+VcCheckOpcodeBytes (
+  IN OUT GHCB*Ghcb,
+  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
+  IN OUT CC_INSTRUCTION_DATA *InstructionData,
+  IN UINT64  ExitCode
+  )
+{
+  UINT8  OpCode;


The linux kernel patch uses "unsigned int opcode" and apparently
checks more than just the first byte for multi-byte opcodes.  Why
do it differently here?

On the bigger picture:  I'm wondering why SNP allows external #VC
injections in the first place?


It does and it doesn't. It doesn't allow #VC when injected as an 
exception. But the case of #VC injected as an interrupt was missed (see 
the event injection type field). It will be fixed in hardware going 
forward, but for now...


Thanks,
Tom



take care,
   Gerd









-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118030): https://edk2.groups.io/g/devel/message/118030
Mute This Topic: https://groups.io/mt/105581633/21656
Mute #vc:https://edk2.groups.io/g/devel/mutehashtag/vc
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 1/2] Platform/AMD: Add AmdSvsmLib to required DSC files

2024-04-15 Thread Lendacky, Thomas via groups.io
Any DSC file that uses the UefiCpuPkg MpInitLib library now requires the
AmdSvsmLib library. Update the DSC files to include the AmdSvsmLib NULL
library implementation. Also, fix the specification of VmgExitLib as it
was renamed to CcExitLib.

Cc: Abner Chang 
Cc: Abdul Lateef Attar 
Cc: Eric Xing 
Signed-off-by: Tom Lendacky 
---
 Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Project.dsc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Project.dsc 
b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Project.dsc
index 20f06dd851..e478e0b0c2 100644
--- a/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Project.dsc
+++ b/Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Project.dsc
@@ -371,7 +371,8 @@
 
 [LibraryClasses.common]
   
RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
-  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
+  CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
 
 [PcdsFixedAtBuild]
   gEfiAmdAgesaPkgTokenSpaceGuid.PcdFchOemBeforePciRestoreSwSmi|0xEA
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117791): https://edk2.groups.io/g/devel/message/117791
Mute This Topic: https://groups.io/mt/105537744/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 2/2] Platform/Intel: Add AmdSvsmLib to required DSC files

2024-04-15 Thread Lendacky, Thomas via groups.io
Any DSC file that uses the UefiCpuPkg MpInitLib library now requires the
AmdSvsmLib library. Update the DSC files to include the AmdSvsmLib NULL
library implementation.

Cc: Leif Lindholm 
Cc: Michael D Kinney 
Cc: Sai Chaganty 
Cc: Nate DeSimone 
Cc: Chasel Chiu 
Cc: Kelly Steele 
Cc: Zailiang Sun 
Signed-off-by: Tom Lendacky 
---
 Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc | 1 +
 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc | 1 +
 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc | 1 +
 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc  | 1 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc   | 1 +
 5 files changed, 5 insertions(+)

diff --git a/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc 
b/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
index 80cc129042..55a67f88b7 100644
--- a/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
+++ b/Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
@@ -38,6 +38,7 @@
   
Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
 
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
 
 [LibraryClasses.common.DXE_CORE, LibraryClasses.common.DXE_DRIVER, 
LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, 
LibraryClasses.common.UEFI_APPLICATION]
   
VariableReadLib|MinPlatformPkg/Library/DxeRuntimeVariableReadLib/DxeRuntimeVariableReadLib.inf
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc 
b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
index 3257156d23..95214a6333 100644
--- a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
@@ -133,6 +133,7 @@
   
PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
 
   #
   # Silicon Package
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc 
b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
index 0c66705377..6e5ad2006d 100644
--- a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc
@@ -163,6 +163,7 @@
   
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
 
   #
diff --git a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc 
b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
index 0689f275f1..31e15d1479 100644
--- a/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
+++ b/Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc
@@ -165,6 +165,7 @@
   
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
   MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
 
   #
diff --git a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc 
b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
index 9452867edb..aae5d05cc5 100644
--- a/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
+++ b/Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc
@@ -596,6 +596,7 @@
   
PciSegmentInfoLib|$(PLATFORM_PKG)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
   
PlatformOpromPolicyLib|$(RP_PKG)/Library/PlatformOpromPolicyLibNull/PlatformOpromPolicyLibNull.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   CrcLib|WhitleyOpenBoardPkg/Library/BaseCrcLib/BaseCrcLib.inf
   
PlatformSpecificAcpiTableLib|WhitleyOpenBoardPkg/Library/PlatformSpecificAcpiTableLibNull/PlatformSpecificAcpiTableLibNull.inf
   
BuildAcpiTablesLib|WhitleyOpenBoardPkg/Library/BuildAcpiTablesLib/DxeBuildAcpiTablesLib.inf
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117790): https://edk2.groups.io/g/devel/message/117790
Mute This Topic: https://groups.io/mt/105537730/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 0/2] Update DSC files to include AmdSvsmLib library

2024-04-15 Thread Lendacky, Thomas via groups.io


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The MpInitLib library was recently updated to use a new library,
AmdSvsmLib. This series adds the AmdSvsmLib library to all DSC files
that use the (non UP) MpInitLib library.

It is meant to be applied in conjunction with the SVSM support series,
after patch number 12:
  UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an SVSM

and before patch number 13:
  UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The series is based off of commit:

  b0c48acdc6a0 ("VirtualKeyboardFeaturePkg: Update the comments of 
ReadKeyStroke and ReadKeyStrokeEx - mantis #2131")

Cc: Ard Biesheuvel 
Cc: Gerd Hoffmann 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Abner Chang 
Cc: Abdul Lateef Attar 
Cc: Eric Xing 
Cc: Leif Lindholm 
Cc: Michael D Kinney 
Cc: Abner Chang 
Cc: Abdul Lateef Attar 
Cc: Eric Xing 
Cc: Sai Chaganty 
Cc: Nate DeSimone 
Cc: Chasel Chiu 
Cc: Kelly Steele 
Cc: Zailiang Sun 

---

Tom Lendacky (2):
  Platform/AMD: Add AmdSvsmLib to required DSC files
  Platform/Intel: Add AmdSvsmLib to required DSC files

 Platform/AMD/VanGoghBoard/ChachaniBoardPkg/Project.dsc   | 3 ++-
 Platform/Intel/MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc | 1 +
 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc | 1 +
 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgIA32.dsc | 1 +
 Platform/Intel/Vlv2TbltDevicePkg/PlatformPkgX64.dsc  | 1 +
 Platform/Intel/WhitleyOpenBoardPkg/PlatformPkg.dsc   | 1 +
 6 files changed, 7 insertions(+), 1 deletion(-)

-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117789): https://edk2.groups.io/g/devel/message/117789
Mute This Topic: https://groups.io/mt/105537725/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-04-12 Thread Lendacky, Thomas via groups.io

On 4/12/24 10:05, Ard Biesheuvel wrote:

On Fri, 12 Apr 2024 at 16:02, Tom Lendacky  wrote:


Re-pinging the list/maintainers, again. I need reviews from the
maintainers on patches #2, #7, #10, #11 and #13.

Once I get final approval, I'll submit the change to edk2-platforms for
the new library as a reply to this series for a quick review.



So this is MdePkg and UefiCpuPkg, right?


MdePkg and UefiPayloadPkg.



@Liming, Mike, Ray: please let me know if you are ok with these


Ray already reviewed/acked the UefiCpuPkg patches.

Looking for
MdePkg: Liming, Mike or Zhiguang
UefiPayloadPkg: Gua, Guo, James or Sean


changes, or whether there are any objections.

I intend to merge this somewhere next week unless there are issues raised.


I'll submit the edk2-platforms series (2 patches, one for Platform/AMD and 
one for Platform/Intel) on Monday, just to have out there.


Thanks,
Tom



Thanks,
Ard.



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117717): https://edk2.groups.io/g/devel/message/117717
Mute This Topic: https://groups.io/mt/104810672/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-04-12 Thread Lendacky, Thomas via groups.io
Re-pinging the list/maintainers, again. I need reviews from the 
maintainers on patches #2, #7, #10, #11 and #13.


Once I get final approval, I'll submit the change to edk2-platforms for 
the new library as a reply to this series for a quick review.


Thanks,
Tom

On 4/2/24 13:16, Lendacky, Thomas via groups.io wrote:
Re-pinging the list/maintainers. Still awaiting feedback/reviews/acks on 
the changes.


Thanks,
Tom

On 3/26/24 13:34, Tom Lendacky wrote:
Any issues with this version of the series? Still looking for 
Reviewed-by's for the MdePkg, UefiCpuPkg and UefiPayloadPkg related 
patches.


Once I get those, I'll submit the edk2-platform patches to support the 
new library as a response to these patches for a quick review.


Thanks,
Tom

On 3/8/24 09:29, Tom Lendacky wrote:


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new AmdSvsmLib library that is used by MpInitLib.
The edk2-platforms repo requires updates/patches to add the new library
requirement. To accomodate that, this series could be split between:

patch number 12:
   UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an SVSM

and patch number 13:
   UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The updates to edk2-platforms can be applied at the split.

This series introduces support to run OVMF under an SVSM. It consists
of:
   - Retrieving the list of vCPU APIC IDs and starting up all APs without
 performing a broadcast SIPI
   - Reorganizing the page state change support to not directly use the
 GHCB buffer since an SVSM will use the calling area buffer, instead
   - Detecting the presence of an SVSM
   - When not running at VMPL0, invoking the SVSM for page validation and
 VMSA page creation/deletion
   - Detecting and allowing OVMF to run in a VMPL other than 0 when an
 SVSM is present

The series is based off of commit:

   e60529df58e4 ("UefiPayloadPkg: Make Dsc accomodative of other archs")

[1] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf
[2] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf


Cc: Anatol Belski 
Cc: Anthony Perard 
Cc: Ard Biesheuvel 
Cc: Corvin Köhne 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Gua Guo 
Cc: Guo Dong 
Cc: James Lu 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Rebecca Cran 
Cc: Sean Rhodes 
Cc: Zhiguang Liu 

---

Changes in v3:
- Renamed CcSvsmLib to a more AMD-specific AmdSvsmLib with corresponding
   function name changes
- Moved the GHCB APIC ID list GUID definition from MdePkg to UefiCpuPkg
   and change the name from gEfiApicIdsGuid to gGhcbApicIdsGuid
- Separated the OvmfPkg changes for the AmdSvsmLib into two patches:
   - First patch adds usage of the AmdSvsmLib NULL library
   - Second patch adds the OVMF AmdSvsmLib implementation
- Updated the commit message for the OVMF AmdSvsmLib implementation to
   indicate that the base functionality for PVALIDATE and RMPADJUST was
   copied from the original locations in prep for converting those sites
   to using the library API.

Changes in v2:
- Move the APIC IDs retrieval support to the beginning of the patch series
 - Use a GUIDed HOB to hold the APIC ID list instead of a PCD
- Split up Page State Change reorganization into multiple patches
- Created CcSvsmLib library instead of extending CcExitLib
 - This will require a corresponding update to edk2-platform DSC files
 - Removed Ray Ni's Acked-by since it is not a minor change
- Variable name changes and other misc changes

Tom Lendacky (24):
   OvmfPkg/BaseMemEncryptLib: Fix error 

Re: [edk2-devel] [RFC PATCH] OvmfPkg/SecurityPkg: Add build option for coexistance of vTPM and RTMR.

2024-04-11 Thread Lendacky, Thomas via groups.io

On 4/11/24 05:33, Ard Biesheuvel wrote:

On Thu, 11 Apr 2024 at 12:29, Gerd Hoffmann  wrote:


On Thu, Apr 11, 2024 at 09:56:48AM +, Yao, Jiewen wrote:

Please allow me to clarify what you are proposing:
Do you mean in vTPM case, we extend both, but we only need TCG event log, NOT 
CC event log?


Elsewhere in this thread it was mentioned that writing both vTPM and
RTMR events to the event log is problematic because the event log format
has no field to specify whenever a given event was measured to vTPM or
RTMR.

If the firmware can make sure all events are measured to both vTPM and
RTMR the need to trace them separately goes away.

So, yes, in case a vTPM is present the firmware would:
   (a) expose EFI_TCG2_PROTOCOL, measure to both vTPM + RTMR
   (b) not expose EFI_CC_MEASUREMENT_PROTOCOL
   (c) log measurements to TCG event log



A TDX attestation would require the PCR to RTMR mapping used by the
firmware in order to reconstruct the RTMR values from the TCG event
log, but that seems feasible to me.

In any case, I think it should be the guest firmware's job to abstract
away the difference.


Agreed, this approach seems to be the best way forward.

Thanks,
Tom


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117633): https://edk2.groups.io/g/devel/message/117633
Mute This Topic: https://groups.io/mt/105070442/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-04-03 Thread Lendacky, Thomas via groups.io

On 4/3/24 02:09, Ni, Ray wrote:

I think I've acked all patches in UefiCpuPkg.
Please let me know if any other patches need my review.


Thanks, Ray!

Tom



Thanks,
Ray

*From:* devel@edk2.groups.io  on behalf of 
Lendacky, Thomas via groups.io 

*Sent:* Wednesday, April 3, 2024 2:16
*To:* devel@edk2.groups.io ; Yao, Jiewen 
; Liming Gao ; Ni, Ray 
; Liu, Zhiguang ; Kinney, 
Michael D ; Guo, Gua ; 
Dong, Guo ; Lu, James ; Rhodes, 
Sean ; Kumar, Rahul R 
*Cc:* Ard Biesheuvel ; Aktas, Erdem 
; Gerd Hoffmann ; Xu, Min M 
; Michael Roth ; Anatol Belski 
; Anthony Perard 
; Corvin Köhne ; 
Jianyong Wu ; Rebecca Cran 
*Subject:* Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for 
running under an SVSM

Re-pinging the list/maintainers. Still awaiting feedback/reviews/acks on
the changes.

Thanks,
Tom

On 3/26/24 13:34, Tom Lendacky wrote:
Any issues with this version of the series? Still looking for 
Reviewed-by's for the MdePkg, UefiCpuPkg and UefiPayloadPkg related 
patches.


Once I get those, I'll submit the edk2-platform patches to support the 
new library as a response to these patches for a quick review.


Thanks,
Tom

On 3/8/24 09:29, Tom Lendacky wrote:


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 

<https://bugzilla.tianocore.org/show_bug.cgi?id=4654>


This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the 
hypervisor.


Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. 
Specifically,

the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new AmdSvsmLib library that is used by MpInitLib.
The edk2-platforms repo requires updates/patches to add the new library
requirement. To accomodate that, this series could be split between:

patch number 12:
   UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an 
SVSM


and patch number 13:
   UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The updates to edk2-platforms can be applied at the split.

This series introduces support to run OVMF under an SVSM. It consists
of:
   - Retrieving the list of vCPU APIC IDs and starting up all APs without
 performing a broadcast SIPI
   - Reorganizing the page state change support to not directly use the
 GHCB buffer since an SVSM will use the calling area buffer, instead
   - Detecting the presence of an SVSM
   - When not running at VMPL0, invoking the SVSM for page validation and
 VMSA page creation/deletion
   - Detecting and allowing OVMF to run in a VMPL other than 0 when an
 SVSM is present

The series is based off of commit:

   e60529df58e4 ("UefiPayloadPkg: Make Dsc accomodative of other archs")

[1] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf <https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf>
[2] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf <https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf>


Cc: Anatol Belski 
Cc: Anthony Perard 
Cc: Ard Biesheuvel 
Cc: Corvin Köhne 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Gua Guo 
Cc: Guo Dong 
Cc: James Lu 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Rebecca Cran 
Cc: Sean Rhodes 
Cc: Zhiguang Liu 

---

Changes in v3:
- Renamed CcSvsmLib to a more AMD-specific AmdSvsmLib with corresponding
   function name changes
- Moved the GHCB APIC ID list GUID definition from MdePkg to UefiCpuPkg
   and change the name from gEfiApicIdsGuid to gGhcbApicIdsGuid
- Separated the OvmfPkg changes for the AmdSvsmLib into two patches:
   - First patch adds usage of the AmdSvsmLib NULL library
   - Second patch adds the OVMF AmdSvsmLib implementation
- Updated the commit mes

Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-04-02 Thread Lendacky, Thomas via groups.io
Re-pinging the list/maintainers. Still awaiting feedback/reviews/acks on 
the changes.


Thanks,
Tom

On 3/26/24 13:34, Tom Lendacky wrote:
Any issues with this version of the series? Still looking for 
Reviewed-by's for the MdePkg, UefiCpuPkg and UefiPayloadPkg related 
patches.


Once I get those, I'll submit the edk2-platform patches to support the 
new library as a response to these patches for a quick review.


Thanks,
Tom

On 3/8/24 09:29, Tom Lendacky wrote:


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the 
hypervisor.


Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. 
Specifically,

the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new AmdSvsmLib library that is used by MpInitLib.
The edk2-platforms repo requires updates/patches to add the new library
requirement. To accomodate that, this series could be split between:

patch number 12:
   UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an 
SVSM


and patch number 13:
   UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The updates to edk2-platforms can be applied at the split.

This series introduces support to run OVMF under an SVSM. It consists
of:
   - Retrieving the list of vCPU APIC IDs and starting up all APs without
 performing a broadcast SIPI
   - Reorganizing the page state change support to not directly use the
 GHCB buffer since an SVSM will use the calling area buffer, instead
   - Detecting the presence of an SVSM
   - When not running at VMPL0, invoking the SVSM for page validation and
 VMSA page creation/deletion
   - Detecting and allowing OVMF to run in a VMPL other than 0 when an
 SVSM is present

The series is based off of commit:

   e60529df58e4 ("UefiPayloadPkg: Make Dsc accomodative of other archs")

[1] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf
[2] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf


Cc: Anatol Belski 
Cc: Anthony Perard 
Cc: Ard Biesheuvel 
Cc: Corvin Köhne 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Gua Guo 
Cc: Guo Dong 
Cc: James Lu 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Rebecca Cran 
Cc: Sean Rhodes 
Cc: Zhiguang Liu 

---

Changes in v3:
- Renamed CcSvsmLib to a more AMD-specific AmdSvsmLib with corresponding
   function name changes
- Moved the GHCB APIC ID list GUID definition from MdePkg to UefiCpuPkg
   and change the name from gEfiApicIdsGuid to gGhcbApicIdsGuid
- Separated the OvmfPkg changes for the AmdSvsmLib into two patches:
   - First patch adds usage of the AmdSvsmLib NULL library
   - Second patch adds the OVMF AmdSvsmLib implementation
- Updated the commit message for the OVMF AmdSvsmLib implementation to
   indicate that the base functionality for PVALIDATE and RMPADJUST was
   copied from the original locations in prep for converting those sites
   to using the library API.

Changes in v2:
- Move the APIC IDs retrieval support to the beginning of the patch 
series

 - Use a GUIDed HOB to hold the APIC ID list instead of a PCD
- Split up Page State Change reorganization into multiple patches
- Created CcSvsmLib library instead of extending CcExitLib
 - This will require a corresponding update to edk2-platform DSC 
files

 - Removed Ray Ni's Acked-by since it is not a minor change
- Variable name changes and other misc changes

Tom Lendacky (24):
   OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()
   MdePkg: GHCB APIC ID retrieval support definitions
   UefiCpuPkg/MpInitLib: Always use AP Create if GhcbApicIds HOB is
 present
   OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
   OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors
   OvmfPkg/BaseMemEncryptSevLib: Calculate 

Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-03-26 Thread Lendacky, Thomas via groups.io
Any issues with this version of the series? Still looking for 
Reviewed-by's for the MdePkg, UefiCpuPkg and UefiPayloadPkg related patches.


Once I get those, I'll submit the edk2-platform patches to support the new 
library as a response to these patches for a quick review.


Thanks,
Tom

On 3/8/24 09:29, Tom Lendacky wrote:


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new AmdSvsmLib library that is used by MpInitLib.
The edk2-platforms repo requires updates/patches to add the new library
requirement. To accomodate that, this series could be split between:

patch number 12:
   UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an SVSM

and patch number 13:
   UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The updates to edk2-platforms can be applied at the split.

This series introduces support to run OVMF under an SVSM. It consists
of:
   - Retrieving the list of vCPU APIC IDs and starting up all APs without
 performing a broadcast SIPI
   - Reorganizing the page state change support to not directly use the
 GHCB buffer since an SVSM will use the calling area buffer, instead
   - Detecting the presence of an SVSM
   - When not running at VMPL0, invoking the SVSM for page validation and
 VMSA page creation/deletion
   - Detecting and allowing OVMF to run in a VMPL other than 0 when an
 SVSM is present

The series is based off of commit:

   e60529df58e4 ("UefiPayloadPkg: Make Dsc accomodative of other archs")

[1] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf
[2] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf

Cc: Anatol Belski 
Cc: Anthony Perard 
Cc: Ard Biesheuvel 
Cc: Corvin Köhne 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Gua Guo 
Cc: Guo Dong 
Cc: James Lu 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Rebecca Cran 
Cc: Sean Rhodes 
Cc: Zhiguang Liu 

---

Changes in v3:
- Renamed CcSvsmLib to a more AMD-specific AmdSvsmLib with corresponding
   function name changes
- Moved the GHCB APIC ID list GUID definition from MdePkg to UefiCpuPkg
   and change the name from gEfiApicIdsGuid to gGhcbApicIdsGuid
- Separated the OvmfPkg changes for the AmdSvsmLib into two patches:
   - First patch adds usage of the AmdSvsmLib NULL library
   - Second patch adds the OVMF AmdSvsmLib implementation
- Updated the commit message for the OVMF AmdSvsmLib implementation to
   indicate that the base functionality for PVALIDATE and RMPADJUST was
   copied from the original locations in prep for converting those sites
   to using the library API.

Changes in v2:
- Move the APIC IDs retrieval support to the beginning of the patch series
 - Use a GUIDed HOB to hold the APIC ID list instead of a PCD
- Split up Page State Change reorganization into multiple patches
- Created CcSvsmLib library instead of extending CcExitLib
 - This will require a corresponding update to edk2-platform DSC files
 - Removed Ray Ni's Acked-by since it is not a minor change
- Variable name changes and other misc changes

Tom Lendacky (24):
   OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()
   MdePkg: GHCB APIC ID retrieval support definitions
   UefiCpuPkg/MpInitLib: Always use AP Create if GhcbApicIds HOB is
 present
   OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
   OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors
   OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State
 Change
   MdePkg: Avoid hardcoded value for number of Page State Change entries
   OvmfPkg/BaseMemEncryptSevLib: Re-organize 

Re: [edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-03-08 Thread Lendacky, Thomas via groups.io

On 3/8/24 09:30, Lendacky, Thomas via groups.io wrote:


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new AmdSvsmLib library that is used by MpInitLib.
The edk2-platforms repo requires updates/patches to add the new library
requirement. To accomodate that, this series could be split between:

patch number 12:
   UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an SVSM

and patch number 13:
   UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The updates to edk2-platforms can be applied at the split.


I have the edk2-platforms patch series prepared but will hold off on 
sending until this series settles and is ready to merge.


Thanks,
Tom






-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116551): https://edk2.groups.io/g/devel/message/116551
Mute This Topic: https://groups.io/mt/104810672/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 24/24] OvmfPkg/BaseMemEncryptLib: Check for presence of an SVSM when not at VMPL0

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Currently, an SEV-SNP guest will terminate if it is not running at VMPL0.
The requirement for running at VMPL0 is removed if an SVSM is present.

Update the current VMPL0 check to additionally check for the presence of
an SVSM is the guest is not running at VMPL0.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c | 9 
++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
index ca279d77274b..227e9910 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "SnpPageStateChange.h"
 
@@ -74,10 +75,12 @@ MemEncryptSevSnpPreValidateSystemRam (
 
   //
   // The page state change uses the PVALIDATE instruction. The instruction
-  // can be run on VMPL-0 only. If its not VMPL-0 guest then terminate
-  // the boot.
+  // can be run at VMPL-0 only. If its not a VMPL-0 guest, then an SVSM must
+  // be present to perform the operation on behalf of the guest. If the guest
+  // is not running at VMPL-0 and an SVSM is not present, then terminate the
+  // boot.
   //
-  if (!SevSnpIsVmpl0 ()) {
+  if (!SevSnpIsVmpl0 () && !AmdSvsmIsSvsmPresent ()) {
 SnpPageStateFailureTerminate ();
   }
 
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116549): https://edk2.groups.io/g/devel/message/116549
Mute This Topic: https://groups.io/mt/104810750/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 23/24] Ovmfpkg/CcExitLib: Provide SVSM discovery support

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SVSM specification documents an alternative method of discovery for
the SVSM using a reserved CPUID bit and a reserved MSR.

For the CPUID support, the #VC handler of an SEV-SNP guest should modify
the returned value in the EAX register for the 0x801f CPUID function
by setting bit 28 when an SVSM is present.

For the MSR support, new reserved MSR 0xc001f000 has been defined. A #VC
should be generated when accessing this MSR. The #VC handler is expected
to ignore writes to this MSR and return the physical calling area address
(CAA) on reads of this MSR.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/CcExitLib/CcExitLib.inf |  3 +-
 OvmfPkg/Library/CcExitLib/SecCcExitLib.inf  |  3 +-
 OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 29 ++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/Library/CcExitLib/CcExitLib.inf 
b/OvmfPkg/Library/CcExitLib/CcExitLib.inf
index bc75cd5f5a04..e09f18453ac9 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitLib.inf
+++ b/OvmfPkg/Library/CcExitLib/CcExitLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  CcExitLib Library.
 #
-#  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #  Copyright (C) 2020 - 2022, Intel Corporation. All rights reserved.
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -41,6 +41,7 @@ [LibraryClasses]
   DebugLib
   LocalApicLib
   MemEncryptSevLib
+  AmdSvsmLib
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase
diff --git a/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf 
b/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
index 811269dd2c06..dff6cd2761ca 100644
--- a/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
+++ b/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  VMGEXIT Support Library.
 #
-#  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -41,6 +41,7 @@ [LibraryClasses]
   LocalApicLib
   MemEncryptSevLib
   PcdLib
+  AmdSvsmLib
 
 [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c 
b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
index 0fc30f7bc4f6..0b61d28f8b94 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
@@ -1,7 +1,7 @@
 /** @file
   X64 #VC Exception Handler functon.
 
-  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -713,10 +714,29 @@ MsrExit (
   IN CC_INSTRUCTION_DATA *InstructionData
   )
 {
-  UINT64  ExitInfo1, Status;
+  MSR_SVSM_CAA_REGISTER  Msr;
+  UINT64 ExitInfo1;
+  UINT64 Status;
 
   ExitInfo1 = 0;
 
+  //
+  // The SVSM CAA MSR is a software implemented MSR and not supported
+  // by the hardware, handle it directly.
+  //
+  if (Regs->Rax == MSR_SVSM_CAA) {
+// Writes to the SVSM CAA MSR are ignored
+if (*(InstructionData->OpCodes + 1) == 0x30) {
+  return 0;
+}
+
+Msr.Uint64 = AmdSvsmSnpGetCaa ();
+Regs->Rax  = Msr.Bits.Lower32Bits;
+Regs->Rdx  = Msr.Bits.Upper32Bits;
+
+return 0;
+  }
+
   switch (*(InstructionData->OpCodes + 1)) {
 case 0x30: // WRMSR
   ExitInfo1  = 1;
@@ -1388,6 +1408,11 @@ GetCpuidFw (
 *Ebx = (*Ebx & 0xFF00) | (Ebx2 & 0x00FF);
 /* node ID */
 *Ecx = (*Ecx & 0xFF00) | (Ecx2 & 0x00FF);
+  } else if (EaxIn == 0x801F) {
+/* Set the SVSM feature bit if running under an SVSM */
+if (AmdSvsmIsSvsmPresent ()) {
+  *Eax |= BIT28;
+}
   }
 
 Out:
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116548): https://edk2.groups.io/g/devel/message/116548
Mute This Topic: https://groups.io/mt/104810747/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 22/24] UefiCpuPkg/MpInitLib: AP creation support under an SVSM

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When running under an SVSM, the VMPL level of the APs that are started
must match the VMPL level provided by the SVSM. Additionally, each AP
must have a Calling Area for use with the SVSM protocol. Update the AP
creation to properly support running under an SVSM.

Cc: Gerd Hoffmann 
Cc: Laszlo Ersek 
Cc: Rahul Kumar 
Cc: Ray Ni 
Acked-by: Ray Ni 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 28 +---
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index 981135621384..bbdc47b5a314 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -44,7 +44,8 @@ SevSnpPerformApAction (
 
   if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
 //
-// Turn the page into a recognized VMSA page.
+// Turn the page into a recognized VMSA page. When an SVSM is present
+// the page following the VMSA is the Calling Area page.
 //
 VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
 if (EFI_ERROR (VmsaStatus)) {
@@ -56,6 +57,7 @@ SevSnpPerformApAction (
   }
 
   ExitInfo1  = (UINT64)ApicId << 32;
+  ExitInfo1 |= (UINT64)SaveArea->Vmpl << 16;
   ExitInfo1 |= Action;
   ExitInfo2  = (UINT64)(UINTN)SaveArea;
 
@@ -87,8 +89,9 @@ SevSnpPerformApAction (
 
   if (Action == SVM_VMGEXIT_SNP_AP_DESTROY) {
 //
-// Make the current VMSA not runnable and accessible to be
-// reprogrammed.
+// Make the current VMSA not runnable and accessible to be reprogrammed.
+// When an SVSM is present the page following the VMSA is the Calling Area
+// page.
 //
 VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
 if (EFI_ERROR (VmsaStatus)) {
@@ -116,6 +119,7 @@ SevSnpCreateSaveArea (
   UINT32  ApicId
   )
 {
+  UINTN PageCount;
   UINT8 *Pages;
   SEV_ES_SAVE_AREA  *SaveArea;
   IA32_CR0  ApCr0;
@@ -125,13 +129,19 @@ SevSnpCreateSaveArea (
   UINTN StartIp;
   UINT8 SipiVector;
 
+  //
+  // When running under an SVSM, a Calling Area page is also needed and is
+  // always the page following the VMSA.
+  //
+  PageCount = AmdSvsmIsSvsmPresent () ? 2 : 1;
+
   if (CpuData->SevEsSaveArea == NULL) {
 //
 // Allocate a page for the SEV-ES Save Area and initialize it. Due to AMD
 // erratum #1467 (VMSA cannot be on a 2MB boundary), allocate an extra page
 // to choose from to work around the issue.
 //
-Pages = AllocateReservedPages (2);
+Pages = AllocateReservedPages (PageCount + 1);
 if (!Pages) {
   return;
 }
@@ -140,12 +150,12 @@ SevSnpCreateSaveArea (
 // Since page allocation works by allocating downward in the address space,
 // try to always free the first (lower address) page to limit possible 
holes
 // in the memory map. So, if the address of the second page is 2MB aligned,
-// then use the first page and free the second page. Otherwise, free the
+// then use the first page and free the last page. Otherwise, free the
 // first page and use the second page.
 //
 if (_IS_ALIGNED (Pages + EFI_PAGE_SIZE, SIZE_2MB)) {
   SaveArea = (SEV_ES_SAVE_AREA *)Pages;
-  FreePages (Pages + EFI_PAGE_SIZE, 1);
+  FreePages (Pages + (EFI_PAGE_SIZE * PageCount), 1);
 } else {
   SaveArea = (SEV_ES_SAVE_AREA *)(Pages + EFI_PAGE_SIZE);
   FreePages (Pages, 1);
@@ -163,7 +173,7 @@ SevSnpCreateSaveArea (
 }
   }
 
-  ZeroMem (SaveArea, EFI_PAGE_SIZE);
+  ZeroMem (SaveArea, EFI_PAGE_SIZE * PageCount);
 
   //
   // Propogate the CR0.NW and CR0.CD setting to the AP
@@ -239,10 +249,10 @@ SevSnpCreateSaveArea (
 
   //
   // Set the SEV-SNP specific fields for the save area:
-  //   VMPL - always VMPL0
+  //   VMPL - based on current mode
   //   SEV_FEATURES - equivalent to the SEV_STATUS MSR right shifted 2 bits
   //
-  SaveArea->Vmpl= 0;
+  SaveArea->Vmpl= AmdSvsmSnpGetVmpl ();
   SaveArea->SevFeatures = AsmReadMsr64 (MSR_SEV_STATUS) >> 2;
 
   SevSnpPerformApAction (SaveArea, ApicId, SVM_VMGEXIT_SNP_AP_CREATE);
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116547): https://edk2.groups.io/g/devel/message/116547
Mute This Topic: https://groups.io/mt/104810744/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 21/24] OvmfPkg/AmdSvsmLib: Add support for the SVSM create/delete vCPU calls

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to alter the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. When
an SVSM is present, use the SVSM_CORE_CREATE_VCPU and SVSM_CORE_DELTE_VCPU
calls to add or remove the VMSA attribute on a page instead of issuing
the RMPADJUST instruction directly.

Implement the AmdSvsmSnpVmsaRmpAdjust() API to perform the proper operation
to update the VMSA attribute.

Cc: Ard Biesheuvel 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c | 54 +++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c 
b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
index fb3fda70e948..6c79ee7d916b 100644
--- a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
+++ b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
@@ -377,6 +377,57 @@ AmdSvsmSnpPvalidate (
   AmdSvsmIsSvsmPresent () ? SvsmPvalidate (Info) : BasePvalidate (Info);
 }
 
+/**
+  Perform an RMPADJUST operation to alter the VMSA setting of a page.
+
+  Add or remove the VMSA attribute for a page.
+
+  @param[in]   Vmsa   Pointer to an SEV-ES save area page
+  @param[in]   ApicId APIC ID associated with the VMSA
+  @param[in]   SetVmsaBoolean indicator as to whether to set or
+  or clear the VMSA setting for the page
+
+  @retval  EFI_SUCCESSRMPADJUST operation successful
+  @retval  EFI_UNSUPPORTEDOperation is not supported
+  @retval  EFI_INVALID_PARAMETER  RMPADJUST operation failed, an invalid
+  parameter was supplied
+
+**/
+STATIC
+EFI_STATUS
+SvsmVmsaRmpAdjust (
+  IN SEV_ES_SAVE_AREA  *Vmsa,
+  IN UINT32ApicId,
+  IN BOOLEAN   SetVmsa
+  )
+{
+  SVSM_CALL_DATA  SvsmCallData;
+  SVSM_FUNCTION   Function;
+  UINTN   Ret;
+
+  SvsmCallData.Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();
+
+  Function.Id.Protocol = 0;
+
+  if (SetVmsa) {
+Function.Id.CallId = 2;
+
+SvsmCallData.RaxIn = Function.Uint64;
+SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+SvsmCallData.RdxIn = (UINT64)(UINTN)Vmsa + SIZE_4KB;
+SvsmCallData.R8In  = ApicId;
+  } else {
+Function.Id.CallId = 3;
+
+SvsmCallData.RaxIn = Function.Uint64;
+SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+  }
+
+  Ret = SvsmMsrProtocol ();
+
+  return (Ret == 0) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+}
+
 /**
   Perform a native RMPADJUST operation to alter the VMSA setting of a page.
 
@@ -444,5 +495,6 @@ AmdSvsmSnpVmsaRmpAdjust (
   IN BOOLEAN   SetVmsa
   )
 {
-  return BaseVmsaRmpAdjust (Vmsa, SetVmsa);
+  return AmdSvsmIsSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa)
+: BaseVmsaRmpAdjust (Vmsa, SetVmsa);
 }
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116546): https://edk2.groups.io/g/devel/message/116546
Mute This Topic: https://groups.io/mt/104810739/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 20/24] OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Similar to the Page State Change optimization added previously, also take
into account the possiblity of using the SVSM for PVALIDATE instructions.
Conditionally adjust the maximum number of entries based on how many
entries the SVSM calling area can support.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 7 
+++
 1 file changed, 7 insertions(+)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index c8c0c4ef0e95..e073f3937c41 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -18,6 +18,7 @@
 
 #include 
 #include 
+#include 
 
 #include "SnpPageStateChange.h"
 
@@ -78,6 +79,7 @@ BuildPageStateBuffer (
   UINTN Index;
   UINTN IndexMax;
   UINTN PscIndexMax;
+  UINTN SvsmIndexMax;
 
   // Clear the page state structure
   SetMem (Info, InfoSize, 0);
@@ -96,6 +98,11 @@ BuildPageStateBuffer (
 IndexMax = MIN (IndexMax, PscIndexMax);
   }
 
+  SvsmIndexMax = (IndexMax / SVSM_PVALIDATE_MAX_ENTRY) * 
SVSM_PVALIDATE_MAX_ENTRY;
+  if (SvsmIndexMax > 0) {
+IndexMax = MIN (IndexMax, SvsmIndexMax);
+  }
+
   //
   // Populate the page state entry structure
   //
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116545): https://edk2.groups.io/g/devel/message/116545
Mute This Topic: https://groups.io/mt/104810737/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 18/24] OvmfPkg: Create a calling area used to communicate with the SVSM

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

An SVSM requires a calling area page whose address (CAA) is used by the
SVSM to communicate and process the SVSM request.

Add a pre-defined page area to the OvmfPkg and AmdSev packages and define
corresponding PCDs used to communicate the location and size of the area.
Keep the AmdSev package in sync with the OvmfPkg and adjust the AmdSev
launch and hash area memory locations.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/OvmfPkg.dec |  4 
 OvmfPkg/AmdSev/AmdSevX64.fdf|  9 ++---
 OvmfPkg/OvmfPkgX64.fdf  |  3 +++
 OvmfPkg/PlatformPei/PlatformPei.inf |  2 ++
 OvmfPkg/ResetVector/ResetVector.inf |  2 ++
 OvmfPkg/PlatformPei/AmdSev.c| 11 +++
 OvmfPkg/ResetVector/ResetVector.nasmb   |  6 --
 OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm | 11 ++-
 8 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index fbc81e4c8070..2f7bded9260b 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -338,6 +338,10 @@ [PcdsFixedAtBuild]
   ## Restrict boot to EFI applications in firmware volumes.
   gUefiOvmfPkgTokenSpaceGuid.PcdBootRestrictToFirmware|FALSE|BOOLEAN|0x6c
 
+  ## The base address and size of the initial SVSM Calling Area.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase|0|UINT32|0x70
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize|0|UINT32|0x71
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index b84981e7ba04..d49555c6c873 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -68,13 +68,16 @@ [FD.MEMFD]
 0x00E000|0x001000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
 
-0x00F000|0x000C00
+0x00F000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
+
+0x01|0x000C00
 
gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
 
-0x00FC00|0x000400
+0x010C00|0x000400
 
gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
 
-0x01|0x01
+0x011000|0x00F000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
 0x02|0x0E
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index eb3fb90cb8b6..d41d8ea7370d 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -94,6 +94,9 @@ [FD.MEMFD]
 0x00E000|0x001000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
 
+0x00F000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
+
 0x01|0x01
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index 2206316fec9e..20b1b9829225 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -128,6 +128,8 @@ [FixedPcd]
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
b/OvmfPkg/ResetVector/ResetVector.inf
index 65f71b05a02e..7bd517e63a0d 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -62,6 +62,8 @@ [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index a9de33074a69..e6724cf493a7 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -555,5 +555,16 @@ SevInitializeRam (
   (UINT64)(UINTN)PcdGet32 (PcdOvmfCpuidSize),
   EfiReservedMemoryType
   );
+
+//
+// The calling area memory needs to be protected until the OS can create
+// its 

[edk2-devel] [PATCH v3 19/24] OvmfPkg/AmdSvsmLib: Add support for the SVSM_CORE_PVALIDATE call

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The PVALIDATE instruction can only be performed at VMPL0. An SVSM will
be present when running at VMPL1 or higher.

When an SVSM is present, use the SVSM_CORE_PVALIDATE call to perform
memory validation instead of issuing the PVALIDATE instruction directly.

Cc: Ard Biesheuvel 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c | 183 +++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c 
b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
index 861bf9591ae3..fb3fda70e948 100644
--- a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
+++ b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
@@ -8,6 +8,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +44,78 @@ SnpTerminate (
   CpuDeadLoop ();
 }
 
+/**
+  Issue an SVSM request.
+
+  Invokes the SVSM to process a request on behalf of the guest.
+
+  @param[in,out]  SvsmCallData  Pointer to the SVSM call data
+
+  @return   Contents of RAX upon return from VMGEXIT
+**/
+STATIC
+UINTN
+SvsmMsrProtocol (
+  IN OUT SVSM_CALL_DATA  *SvsmCallData
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  UINT64CurrentMsr;
+  UINT8 Pending;
+  BOOLEAN   InterruptState;
+  UINTN Ret;
+
+  do {
+//
+// Be sure that an interrupt can't cause a #VC while the GHCB MSR protocol
+// is being used (#VC handler will ASSERT if lower 12-bits are not zero).
+//
+InterruptState = GetInterruptState ();
+if (InterruptState) {
+  DisableInterrupts ();
+}
+
+Pending   = 0;
+SvsmCallData->CallPending = 
+
+CurrentMsr = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+Msr.Uint64  = 0;
+Msr.SnpVmplRequest.Function = GHCB_INFO_SNP_VMPL_REQUEST;
+Msr.SnpVmplRequest.Vmpl = 0;
+AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.Uint64);
+
+//
+// Guest memory is used for the guest-SVSM communication, so fence the
+// invocation of the VMGEXIT instruction to ensure VMSA accesses are
+// synchronized properly.
+//
+MemoryFence ();
+Ret = AsmVmgExitSvsm (SvsmCallData);
+MemoryFence ();
+
+Msr.Uint64 = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr);
+
+if (InterruptState) {
+  EnableInterrupts ();
+}
+
+if (Pending != 0) {
+  SnpTerminate ();
+}
+
+if ((Msr.SnpVmplResponse.Function != GHCB_INFO_SNP_VMPL_RESPONSE) ||
+(Msr.SnpVmplResponse.ErrorCode != 0))
+{
+  SnpTerminate ();
+}
+  } while (Ret == SVSM_ERR_INCOMPLETE || Ret == SVSM_ERR_BUSY);
+
+  return Ret;
+}
+
 /**
   Report the presence of an Secure Virtual Services Module (SVSM).
 
@@ -109,6 +182,114 @@ AmdSvsmSnpGetCaa (
   return AmdSvsmIsSvsmPresent () ? SvsmInfo->SvsmCaa : 0;
 }
 
+/**
+  Issue an SVSM request to perform the PVALIDATE instruction.
+
+  Invokes the SVSM to process the PVALIDATE instruction on behalf of the
+  guest to validate or invalidate the memory range specified.
+
+  @param[in]   Info   Pointer to a page state change structure
+
+**/
+STATIC
+VOID
+SvsmPvalidate (
+  IN SNP_PAGE_STATE_CHANGE_INFO  *Info
+  )
+{
+  SVSM_CALL_DATA  SvsmCallData;
+  SVSM_CAA*Caa;
+  SVSM_PVALIDATE_REQUEST  *Request;
+  SVSM_FUNCTION   Function;
+  BOOLEAN Validate;
+  UINTN   Entry;
+  UINTN   EntryLimit;
+  UINTN   Index;
+  UINTN   EndIndex;
+  UINT64  Gfn;
+  UINT64  GfnEnd;
+  UINTN   Ret;
+
+  Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();
+  ZeroMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer));
+
+  Function.Id.Protocol = 0;
+  Function.Id.CallId   = 1;
+
+  Request= (SVSM_PVALIDATE_REQUEST *)Caa->SvsmBuffer;
+  EntryLimit = ((sizeof (Caa->SvsmBuffer) - sizeof (*Request)) /
+sizeof (Request->Entry[0])) - 1;
+
+  SvsmCallData.Caa   = Caa;
+  SvsmCallData.RaxIn = Function.Uint64;
+  SvsmCallData.RcxIn = (UINT64)(UINTN)Request;
+
+  Entry= 0;
+  Index= Info->Header.CurrentEntry;
+  EndIndex = Info->Header.EndEntry;
+
+  while (Index <= EndIndex) {
+Validate = Info->Entry[Index].Operation == SNP_PAGE_STATE_PRIVATE;
+
+Request->Header.Entries++;
+Request->Entry[Entry].Bits.PageSize = Info->Entry[Index].PageSize;
+Request->Entry[Entry].Bits.Action   = (Validate == TRUE) ? 1 : 0;
+Request->Entry[Entry].Bits.IgnoreCf = 0;
+Request->Entry[Entry].Bits.Address  = Info->Entry[Index].GuestFrameNumber;
+
+Entry++;
+if ((Entry > EntryLimit) || (Index == EndIndex)) {
+  Ret = SvsmMsrProtocol ();
+  if ((Ret == SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH) &&
+  (Request->Entry[Request->Header.Next].Bits.PageSize != 0))
+   

[edk2-devel] [PATCH v3 17/24] OvmfPkg/BaseMemEncryptSevLib: Use AmdSvsmSnpPvalidate() to validate pages

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The PVALIDATE instruction is used to change the SNP validation of a page,
but that can only be done when running at VMPL0. To prepare for running at
a less priviledged VMPL, use the AmdSvsmLib library API to perform the
PVALIDATE. The AmdSvsmLib library will perform the proper operation on
behalf of the caller.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf  |  3 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf  |  3 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf  |  3 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 74 
+---
 4 files changed, 9 insertions(+), 74 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
index cc24961c9265..312ee73e5474 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Library provides the helper functions for SEV guest
 #
-# Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -52,6 +52,7 @@ [LibraryClasses]
   MemoryAllocationLib
   PcdLib
   CcExitLib
+  AmdSvsmLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 8f56783da55e..1e0b5600eb1d 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Library provides the helper functions for SEV guest
 #
-# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -52,6 +52,7 @@ [LibraryClasses]
   MemoryAllocationLib
   PcdLib
   CcExitLib
+  AmdSvsmLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
index b6d76e7e630f..a06ea6188eab 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Library provides the helper functions for SEV guest
 #
-# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -49,6 +49,7 @@ [LibraryClasses]
   DebugLib
   PcdLib
   CcExitLib
+  AmdSvsmLib
 
 [FixedPcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index f1883239a661..c8c0c4ef0e95 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -14,14 +14,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
 #include "SnpPageStateChange.h"
 
-#define PAGES_PER_LARGE_ENTRY  512
-
 STATIC
 UINTN
 MemoryStateToGhcbOp (
@@ -63,73 +62,6 @@ SnpPageStateFailureTerminate (
   CpuDeadLoop ();
 }
 
-/**
- This function issues the PVALIDATE instruction to validate or invalidate the 
memory
- range specified. If PVALIDATE returns size mismatch then it retry validating 
with
- smaller page size.
-
- */
-STATIC
-VOID
-PvalidateRange (
-  IN  SNP_PAGE_STATE_CHANGE_INFO  *Info
-  )
-{
-  UINTN RmpPageSize;
-  UINTN StartIndex;
-  UINTN EndIndex;
-  UINTN Index;
-  UINTN Ret;
-  EFI_PHYSICAL_ADDRESS  Address;
-  BOOLEAN   Validate;
-
-  StartIndex = Info->Header.CurrentEntry;
-  EndIndex   = Info->Header.EndEntry;
-
-  for ( ; StartIndex <= EndIndex; StartIndex++) {
-//
-// Get the address and the page size from the Info.
-//
-Address = 
((EFI_PHYSICAL_ADDRESS)Info->Entry[StartIndex].GuestFrameNumber) << 
EFI_PAGE_SHIFT;
-RmpPageSize = Info->Entry[StartIndex].PageSize;
-Validate= Info->Entry[StartIndex].Operation == SNP_PAGE_STATE_PRIVATE;
-
-Ret = AsmPvalidate (RmpPageSize, Validate, Address);
-
-//
-// If we fail to validate due to size mismatch then try with the
-// smaller page size. This senario will occur if the backing page in
-// the RMP 

[edk2-devel] [PATCH v3 16/24] UefiCpuPkg/MpInitLib: Use AmdSvsmSnpVmsaRmpAdjust() to set/clear VMSA

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to change the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. To
prepare for running at a less priviledged VMPL, use the AmdSvsmLib library
API to perform the RMPADJUST. The AmdSvsmLib library will perform the
proper operation on behalf of the caller.

Cc: Gerd Hoffmann 
Cc: Laszlo Ersek 
Cc: Rahul Kumar 
Cc: Ray Ni 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/MpLib.h  | 14 -
 UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c| 20 
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 54 +++-
 5 files changed, 9 insertions(+), 81 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 69950fcd1289..19745437f005 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -57,6 +57,7 @@ [LibraryClasses]
   SynchronizationLib
   PcdLib
   CcExitLib
+  AmdSvsmLib
   MicrocodeLib
 [LibraryClasses.X64]
   CpuPageTableLib
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 22f74a814534..679e51a1acd5 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -53,6 +53,7 @@ [LibraryClasses]
   PeiServicesLib
   PcdLib
   CcExitLib
+  AmdSvsmLib
   MicrocodeLib
 
 [Pcd]
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 65e05c4806f5..179f8e585b5d 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -883,20 +883,6 @@ FillExchangeInfoDataSevEs (
   IN volatile MP_CPU_EXCHANGE_INFO  *ExchangeInfo
   );
 
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  );
-
 /**
   Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index 0478e92317f1..963bd62494b9 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
@@ -49,26 +49,6 @@ SevSnpCreateAP (
   ASSERT (FALSE);
 }
 
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  )
-{
-  //
-  // RMPADJUST is not supported in 32-bit mode
-  //
-  return RETURN_UNSUPPORTED;
-}
-
 /**
   Determine if the SEV-SNP AP Create protocol should be used.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index bd12a5ee2fcb..981135621384 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -10,6 +10,7 @@
 
 #include "MpLib.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -38,20 +39,15 @@ SevSnpPerformApAction (
   BOOLEAN   InterruptState;
   UINT64ExitInfo1;
   UINT64ExitInfo2;
-  UINT32RmpAdjustStatus;
   UINT64VmgExitStatus;
+  EFI_STATUSVmsaStatus;
 
   if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
 //
-// To turn the page into a recognized VMSA page, issue RMPADJUST:
-//   Target VMPL but numerically higher than current VMPL
-//   Target PermissionMask is not used
+// Turn the page into a recognized VMSA page.
 //
-RmpAdjustStatus = SevSnpRmpAdjust (
-(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
-TRUE
-);
-if (RmpAdjustStatus != 0) {
+VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
+if (EFI_ERROR (VmsaStatus)) {
   DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA creation\n"));
   ASSERT (FALSE);
 
@@ -94,11 +90,8 @@ SevSnpPerformApAction (
 // Make the current VMSA not runnable and accessible to be
 // reprogrammed.
 //
-RmpAdjustStatus = SevSnpRmpAdjust (
-(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
-FALSE
-);
-if (RmpAdjustStatus != 0) {
+VmsaStatus = AmdSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
+if (EFI_ERROR (VmsaStatus)) {
   DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA reset\n"));
   ASSERT (FALSE);
 
@@ -328,39 +321,6 @@ SevSnpCreateAP (
   }
 }
 
-/**
-  Issue RMPADJUST to 

[edk2-devel] [PATCH v3 14/24] Ovmfpkg: Prepare OvmfPkg to use the AmdSvsmLib library

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The MpInitLib library will be updated to use the new AmdSvsmLib library.
To prevent any build breakage, update the OvmfPkg DSCs file to include
the AmdSvsmLib NULL library.

Cc: Anatol Belski 
Cc: Anthony Perard 
Cc: Ard Biesheuvel 
Cc: Corvin Köhne 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Rebecca Cran 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/AmdSev/AmdSevX64.dsc | 1 +
 OvmfPkg/Bhyve/BhyveX64.dsc   | 1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc   | 1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 +
 OvmfPkg/Microvm/MicrovmX64.dsc   | 1 +
 OvmfPkg/OvmfPkgIa32.dsc  | 1 +
 OvmfPkg/OvmfPkgIa32X64.dsc   | 3 ++-
 OvmfPkg/OvmfPkgX64.dsc   | 1 +
 OvmfPkg/OvmfXen.dsc  | 1 +
 9 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 60e916b4fd18..140c4208f5b7 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -204,6 +204,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 9689a2f14efa..6f305d690dda 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -232,6 +232,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index b522fa10594d..4dad0a36e757 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -242,6 +242,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 7a767324ffda..6a78d1133880 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -212,6 +212,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 2c6bb83beb85..cc84ee3c2956 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -246,6 +246,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 713f08764b07..15fadc2fdc6e 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -247,6 +247,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
   TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 90b15dc27097..6e55b50a9641 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -4,7 +4,7 @@
 #  Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
 #  (C) Copyright 2016 Hewlett Packard Enterprise Development LP
 #  Copyright (c) Microsoft Corporation.
-#  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -252,6 +252,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   

[edk2-devel] [PATCH v3 15/24] Ovmfpkg/AmdSvsmLib: Create AmdSvsmLib to handle SVSM related services

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Add initial support for the new AmdSvsmLib library to OvmfPkg. The initial
implementation fully implements the library interfaces.

The SVSM presence check, AmdSvsmIsSvsmPresent(), determines the presence
of an SVSM by checking if an SVSM has been advertised in the SEV-SNP
Secrets Page.

The VMPL API, AmdSvsmSnpGetVmpl(), returns the VMPL level at which OVMF is
currently running.

The CAA API, AmdSvsmSnpGetCaa(), returns the Calling Area Address when an
SVSM is present, 0 otherwise.

The PVALIDATE API, AmdSvsmSnpPvalidate(), copies the PVALIDATE logic from
the BaseMemEncryptSevLib library for the initial implementation. The
BaseMemEncryptSevLib library will be changed to use this new API so that
the decision as to whether the SVSM is needed to perform the operation
can be isolated to this library.

The VMSA API, AmdSvsmSnpVmsaRmpAdjust(), copies the RMPUPDATE logic from
the MpInitLib library for the initial implementation. The MpInitLib
library will be changed to use this new API so that the decision as to
whether the SVSM is needed to perform the operation can be isolated to
this library.

Cc: Anatol Belski 
Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/AmdSev/AmdSevX64.dsc  |   2 +-
 OvmfPkg/CloudHv/CloudHvX64.dsc|   2 +-
 OvmfPkg/Microvm/MicrovmX64.dsc|   2 +-
 OvmfPkg/OvmfPkgX64.dsc|   2 +-
 OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf |  38 +++
 OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c   | 267 
 6 files changed, 309 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 140c4208f5b7..a7540bb6367f 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -204,7 +204,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
-  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
+  AmdSvsmLib|OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 4dad0a36e757..b1911d6ab4ac 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -242,7 +242,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
 
 [LibraryClasses.common]
-  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
+  AmdSvsmLib|OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index cc84ee3c2956..1f2f8b5bb618 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -246,7 +246,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
-  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
+  AmdSvsmLib|OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 87e210d4409c..540c1ed8da63 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -268,7 +268,7 @@ [LibraryClasses]
 !include OvmfPkg/Include/Dsc/ShellLibs.dsc.inc
 
 [LibraryClasses.common]
-  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
+  AmdSvsmLib|OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
diff --git a/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf 
b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf
new file mode 100644
index ..cfd2663adc3a
--- /dev/null
+++ b/OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf
@@ -0,0 +1,38 @@
+## @file
+#  CcExitLib Library.
+#
+#  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 1.29
+  BASE_NAME  = AmdSvsmLib
+  FILE_GUID  = 288e3588-87d8-4c2c-b568-bf900de0fb36
+  MODULE_TYPE= BASE
+  VERSION_STRING = 1.0
+  LIBRARY_CLASS  = AmdSvsmLib
+
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES   = X64
+#
+
+[Sources.common]
+  AmdSvsmLib.c
+
+[Packages]
+  

[edk2-devel] [PATCH v3 13/24] UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The MpInitLib library will be updated to use the new AmdSvsmLib library.
To prevent any build breakage, update the UefiPayloadPkg DSC file to
include the AmdSvsmLib NULL library.

Cc: Gua Guo 
Cc: Guo Dong 
Cc: James Lu 
Cc: Sean Rhodes 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc 
b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 433fb51a5695..e1b9d5ecf182 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -313,6 +313,7 @@ [LibraryClasses]
   
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
   
VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
   FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
 [LibraryClasses.common]
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116538): https://edk2.groups.io/g/devel/message/116538
Mute This Topic: https://groups.io/mt/104810720/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 12/24] UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an SVSM

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

In order to support an SEV-SNP guest running under an SVSM at VMPL1 or
lower, a new library must be created.

This library includes an interface to detect if running under an SVSM, an
interface to return the current VMPL, an interface to perform memory
validation and an interface to set or clear the attribute that allows a
page to be used as a VMSA.

Cc: Gerd Hoffmann 
Cc: Laszlo Ersek 
Cc: Rahul Kumar 
Cc: Ray Ni 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/UefiCpuPkg.dec|   3 +
 UefiCpuPkg/UefiCpuPkg.dsc|   4 +-
 UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf |  27 +
 UefiCpuPkg/Include/Library/AmdSvsmLib.h  | 101 ++
 UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.c   | 108 
 UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.uni |  13 +++
 6 files changed, 255 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index c31d8b6736cf..d1bff93ae2e0 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -52,6 +52,9 @@ [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Provides function to support CcExit processing.
   CcExitLib|Include/Library/CcExitLib.h
 
+  ##  @libraryclass  Provides function to support AmdSvsm processing.
+  AmdSvsmLib|Include/Library/AmdSvsmLib.h
+
   ##  @libraryclass  Provides function to get CPU cache information.
   CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h
 
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 10b33594e586..422e50c92b48 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -2,7 +2,7 @@
 #  UefiCpuPkg Package
 #
 #  Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
-#  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -61,6 +61,7 @@ [LibraryClasses]
   
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
   
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
   
SmmCpuRendezvousLib|UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf
   CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
@@ -159,6 +160,7 @@ [Components.IA32, Components.X64]
   UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf
   UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf
   UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
   UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
   UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
   UefiCpuPkg/SecCore/SecCore.inf
diff --git a/UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf 
b/UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
new file mode 100644
index ..45a189540941
--- /dev/null
+++ b/UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
@@ -0,0 +1,27 @@
+## @file
+#  AmdSvsm Base Support Library.
+#
+#  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 1.29
+  BASE_NAME  = AmdSvsmLibNull
+  MODULE_UNI_FILE= AmdSvsmLibNull.uni
+  FILE_GUID  = 62b45e0f-c9b4-45ce-a5b3-41762709b3d9
+  MODULE_TYPE= BASE
+  VERSION_STRING = 1.0
+  LIBRARY_CLASS  = AmdSvsmLib
+
+[Sources.common]
+  AmdSvsmLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+
diff --git a/UefiCpuPkg/Include/Library/AmdSvsmLib.h 
b/UefiCpuPkg/Include/Library/AmdSvsmLib.h
new file mode 100644
index ..40e0e5bd4259
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/AmdSvsmLib.h
@@ -0,0 +1,101 @@
+/** @file
+  Public header file for the AmdSvsmLib.
+
+  This library class defines some routines used for invoking an SVSM when the
+  guest is not running at VMPL0.
+
+  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef AMD_SVSM_LIB_H_
+#define AMD_SVSM_LIB_H_
+
+#include 
+#include 
+
+/**
+  Report the presence of an Secure Virtual Services Module (SVSM).
+
+  Determines the presence of an SVSM.
+
+  @retval  TRUE   An SVSM is present
+  @retval  FALSE  An SVSM is not present
+
+**/
+BOOLEAN
+EFIAPI
+AmdSvsmIsSvsmPresent (
+  VOID
+  );
+
+/**
+  Report the VMPL level at which the SEV-SNP 

[edk2-devel] [PATCH v3 11/24] MdePkg/BaseLib: Add a new VMGEXIT instruction invocation for SVSM

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SVSM specification relies on a specific register calling convention to
hold the parameters that are associated with the SVSM request. The SVSM is
invoked by requesting the hypervisor to run the VMPL0 VMSA of the guest
using the GHCB MSR Protocol or a GHCB NAE event.

Create a new version of the VMGEXIT instruction that will adhere to this
calling convention and load the SVSM function arguments into the proper
register before invoking the VMGEXIT instruction. On return, perform the
atomic exchange on the SVSM call pending value as specified in the SVSM
specification.

Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 MdePkg/Library/BaseLib/BaseLib.inf   |  2 +
 MdePkg/Include/Library/BaseLib.h | 39 
 MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm | 39 
 MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm  | 94 
 4 files changed, 174 insertions(+)

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf 
b/MdePkg/Library/BaseLib/BaseLib.inf
index 4dbe94be71e1..26e66a8d67cf 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -187,6 +187,7 @@ [Sources.Ia32]
   Ia32/XGetBv.nasm
   Ia32/XSetBv.nasm
   Ia32/VmgExit.nasm
+  Ia32/VmgExitSvsm.nasm
 
   Ia32/DivS64x64Remainder.c
   Ia32/InternalSwitchStack.c | MSFT
@@ -328,6 +329,7 @@ [Sources.X64]
   X64/XGetBv.nasm
   X64/XSetBv.nasm
   X64/VmgExit.nasm
+  X64/VmgExitSvsm.nasm
   ChkStkGcc.c  | GCC
 
 [Sources.EBC]
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 1fff0fb224f1..95f805599d9d 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7876,6 +7876,45 @@ AsmVmgExit (
   VOID
   );
 
+///
+/// The structure used to supply and return data to and from the SVSM.
+///
+typedef struct {
+  VOID  *Caa;
+  UINT64RaxIn;
+  UINT64RcxIn;
+  UINT64RdxIn;
+  UINT64R8In;
+  UINT64R9In;
+  UINT64RaxOut;
+  UINT64RcxOut;
+  UINT64RdxOut;
+  UINT64R8Out;
+  UINT64R9Out;
+  UINT8 *CallPending;
+} SVSM_CALL_DATA;
+
+/**
+  Executes a VMGEXIT instruction (VMMCALL with a REP prefix) with arguments
+  and return code
+
+  Executes a VMGEXIT instruction placing the specified arguments in the
+  corresponding registers before invocation. Upon return an XCHG is done to
+  atomically clear and retrieve the SVSM call pending value. The returned RAX
+  register value becomes the function return code. This function is intended
+  for use with an SVSM. This function is only available on IA-32 and x64.
+
+  @param[in,out]  SvsmCallPending  Pointer to the location of the SVSM call 
data
+
+  @return  Value of the RAX register on return
+
+**/
+UINT32
+EFIAPI
+AsmVmgExitSvsm (
+  IN OUT SVSM_CALL_DATA  *SvsmCallData
+  );
+
 /**
   Patch the immediate operand of an IA32 or X64 instruction such that the byte,
   word, dword or qword operand is encoded at the end of the instruction's
diff --git a/MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm 
b/MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm
new file mode 100644
index ..14717bd1af02
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm
@@ -0,0 +1,39 @@
+;--
+;
+; Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   VmgExitSvsm.Asm
+;
+; Abstract:
+;
+;   AsmVmgExitSvsm function
+;
+; Notes:
+;
+;--
+
+DEFAULT REL
+SECTION .text
+
+;--
+; UINT32
+; EFIAPI
+; AsmVmgExitSvsm (
+;   SVSM_CALL_DATA *SvsmCallData
+;   );
+;--
+global ASM_PFX(AsmVmgExitSvsm)
+ASM_PFX(AsmVmgExitSvsm):
+;
+; NASM doesn't support the vmmcall instruction in 32-bit mode and NASM versions
+; before 2.12 cannot translate the 64-bit "rep vmmcall" instruction into elf32
+; format. Given that VMGEXIT does not make sense on IA32, provide a stub
+; implementation that is identical to CpuBreakpoint(). In practice,
+; AsmVmgExitSvsm() should never be called on IA32.
+;
+int  3
+ret
+
diff --git a/MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm 
b/MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm
new file mode 100644
index ..b8af78890611
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm
@@ -0,0 +1,94 @@
+;--
+;
+; Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   VmgExitSvsm.Asm
+;
+; Abstract:
+;
+;   AsmVmgExitSvsm function
+;
+; 

[edk2-devel] [PATCH v3 10/24] MdePkg/Register/Amd: Define the SVSM related information

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The Secure VM Service Module specification defines the interfaces needed
to allow multi-VMPL level execution of an SEV-SNP guest.

Define the SVSM related structures for the SVSM Calling Area as well as
the SVSM CAA MSR. The SVSM CAA MSR is an MSR register that is reserved for
software use and will not be implemented in hardware.

Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 MdePkg/Include/Register/Amd/Fam17Msr.h |  19 +++-
 MdePkg/Include/Register/Amd/Msr.h  |   3 +-
 MdePkg/Include/Register/Amd/Svsm.h | 101 
 MdePkg/Include/Register/Amd/SvsmMsr.h  |  35 +++
 4 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h 
b/MdePkg/Include/Register/Amd/Fam17Msr.h
index bb4e143e2456..f2d5ccb39dc7 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -6,7 +6,7 @@
   returned is a single 32-bit or 64-bit value, then a data structure is not
   provided for that MSR.
 
-  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.
+  Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Specification Reference:
@@ -71,9 +71,24 @@ typedef union {
 UINT32ErrorCode;
   } SnpPageStateChangeResponse;
 
+  struct {
+UINT64Function  : 12;
+UINT64Reserved1 : 20;
+UINT64Vmpl  : 8;
+UINT64Reserved2 : 56;
+  } SnpVmplRequest;
+
+  struct {
+UINT32Function : 12;
+UINT32Reserved : 20;
+UINT32ErrorCode;
+  } SnpVmplResponse;
+
   VOID  *Ghcb;
 
   UINT64GhcbPhysicalAddress;
+
+  UINT64Uint64;
 } MSR_SEV_ES_GHCB_REGISTER;
 
 #define GHCB_INFO_SEV_INFO1
@@ -84,6 +99,8 @@ typedef union {
 #define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE  19
 #define GHCB_INFO_SNP_PAGE_STATE_CHANGE_REQUEST   20
 #define GHCB_INFO_SNP_PAGE_STATE_CHANGE_RESPONSE  21
+#define GHCB_INFO_SNP_VMPL_REQUEST22
+#define GHCB_INFO_SNP_VMPL_RESPONSE   23
 #define GHCB_HYPERVISOR_FEATURES_REQUEST  128
 #define GHCB_HYPERVISOR_FEATURES_RESPONSE 129
 #define GHCB_INFO_TERMINATE_REQUEST   256
diff --git a/MdePkg/Include/Register/Amd/Msr.h 
b/MdePkg/Include/Register/Amd/Msr.h
index 084eb892cdd9..04a3cbeb4315 100644
--- a/MdePkg/Include/Register/Amd/Msr.h
+++ b/MdePkg/Include/Register/Amd/Msr.h
@@ -6,7 +6,7 @@
   returned is a single 32-bit or 64-bit value, then a data structure is not
   provided for that MSR.
 
-  Copyright (c) 2017 - 2019, Advanced Micro Devices. All rights reserved.
+  Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Specification Reference:
@@ -19,5 +19,6 @@
 
 #include 
 #include 
+#include 
 
 #endif
diff --git a/MdePkg/Include/Register/Amd/Svsm.h 
b/MdePkg/Include/Register/Amd/Svsm.h
new file mode 100644
index ..9a989f803107
--- /dev/null
+++ b/MdePkg/Include/Register/Amd/Svsm.h
@@ -0,0 +1,101 @@
+/** @file
+  Secure VM Service Module (SVSM) Definition.
+
+  Provides data types allowing an SEV-SNP guest to interact with the SVSM.
+
+  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Specification Reference:
+  Secure VM Service Module Specification
+
+**/
+
+#ifndef SVSM_H_
+#define SVSM_H_
+
+#include 
+#include 
+#include 
+
+//
+// The SVSM definitions are part of the SNP Secrets Page:
+//   An SVSM is considered present if the SvsmSize field is non-zero.
+//
+typedef PACKED struct {
+  UINT8 Reserved1[320];
+
+  UINT64SvsmBase;
+  UINT64SvsmSize;
+  UINT64SvsmCaa;
+  UINT32SvsmMaxVersion;
+  UINT8 SvsmGuestVmpl;
+  UINT8 Reserved2[3];
+} SVSM_INFORMATION;
+
+typedef PACKED struct {
+  UINT8SvsmCallPending;
+  UINT8SvsmMemAvailable;
+  UINT8Reserved1[6];
+
+  //
+  // The remainder of the CAA 4KB area can be used for argument
+  // passing to the SVSM.
+  //
+  UINT8SvsmBuffer[SIZE_4KB - 8];
+} SVSM_CAA;
+
+#define SVSM_SUCCESS   0x
+#define SVSM_ERR_INCOMPLETE0x8000
+#define SVSM_ERR_UNSUPPORTED_PROTOCOL  0x8001
+#define SVSM_ERR_UNSUPPORTED_CALL  0x8002
+#define SVSM_ERR_INVALID_ADDRESS   0x8003
+#define SVSM_ERR_INVALID_FORMAT0x8004
+#define SVSM_ERR_INVALID_PARAMETER 0x8005
+#define SVSM_ERR_INVALID_REQUEST   0x8006
+#define SVSM_ERR_BUSY  0x8007
+
+#define SVSM_ERR_PVALIDATE_FAIL_INPUT  0x80001001
+#define SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH  0x80001006
+#define SVSM_ERR_PVALIDATE_FAIL_NO_CHANGE  0x80001010
+
+typedef PACKED struct {
+  UINT16Entries;
+  UINT16Next;
+
+  UINT8 Reserved[4];
+} 

[edk2-devel] [PATCH v3 08/24] OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

In preparation for running under an SVSM at VMPL1 or higher (higher
numerically, lower privilege), re-organize the way a page state change
is performed in order to free up the GHCB for use by the SVSM support.

Currently, the page state change logic directly uses the GHCB shared
buffer to build the page state change structures. However, this will be
in conflict with the use of the GHCB should an SVSM call be required.

Instead, use a separate buffer (an area in the workarea during SEC and
an allocated page during PEI/DXE) to hold the page state change request
and only update the GHCB shared buffer as needed.

Since the information is copied to, and operated on, in the GHCB shared
buffer this has the added benefit of not requiring to save the start and
end entries for use when validating the memory during the page state
change sequence.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Include/WorkArea.h|   9 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h |   6 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c|  11 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c|  27 
-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c|  22 
+++-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c|  14 ++-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 109 
+---
 7 files changed, 146 insertions(+), 52 deletions(-)

diff --git a/OvmfPkg/Include/WorkArea.h b/OvmfPkg/Include/WorkArea.h
index b1c7045ce18c..e3b415db2caa 100644
--- a/OvmfPkg/Include/WorkArea.h
+++ b/OvmfPkg/Include/WorkArea.h
@@ -2,7 +2,7 @@
 
   Work Area structure definition
 
-  Copyright (c) 2021, AMD Inc.
+  Copyright (c) 2021 - 2024, AMD Inc.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
@@ -54,6 +54,13 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
   // detection in OvmfPkg/ResetVector/Ia32/AmdSev.c
   //
   UINT8 ReceivedVc;
+  UINT8 Reserved[7];
+
+  // Used by SEC to generate Page State Change requests. This should be
+  // sized less than an equal to the GHCB shared buffer area to allow a
+  // single call to the hypervisor.
+  //
+  UINT8 WorkBuffer[1024];
 } SEC_SEV_ES_WORK_AREA;
 
 //
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
index 43319cc9ed17..5d23d1828b25 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -24,7 +24,9 @@ InternalSetPageState (
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,
   IN UINTN NumPages,
   IN SEV_SNP_PAGE_STATEState,
-  IN BOOLEAN   UseLargeEntry
+  IN BOOLEAN   UseLargeEntry,
+  IN VOID  *PscBuffer,
+  IN UINTN PscBufferSize
   );
 
 VOID
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
index cbcdd46f528f..2515425e467a 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -16,6 +16,8 @@
 #include "SnpPageStateChange.h"
 #include "VirtualMemory.h"
 
+STATIC VOID  *mPscBuffer = NULL;
+
 /**
   Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
 
@@ -52,5 +54,10 @@ MemEncryptSevSnpPreValidateSystemRam (
 }
   }
 
-  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+  if (mPscBuffer == NULL) {
+mPscBuffer = AllocateReservedPages (1);
+ASSERT (mPscBuffer != NULL);
+  }
+
+  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE, 
mPscBuffer, EFI_PAGE_SIZE);
 }
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index dee3fb8914ca..337a7d926b15 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -3,7 +3,7 @@
   Virtual Memory Management Services to set or clear the memory encryption bit
 
   Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
-  

[edk2-devel] [PATCH v3 09/24] OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When building the Page State Change entries for a range of memory, it can
happen that multiple calls to BuildPageStateBuffer() need to be made. If
the size of the input work area passed to BuildPageStateBuffer() exceeds
the number of entries that can be passed to the hypervisor using the GHCB
shared buffer, the Page State Change VMGEXIT support will issue multiple
VMGEXITs to process all entries in the buffer.

However, it could be that the final VMGEXIT for each round of Page State
Changes is only for a small number of entries and subsequent VMGEXITs may
still be issued to handle the full range of memory requested. To maximize
the number of entries processed during the Page State Change VMGEXIT,
limit BuildPageStateBuffer() to not build entries that exceed the maximum
number of entries that can be handled in a single Page State Change
VMGEXIT.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 11 
+++
 1 file changed, 11 insertions(+)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index bcc0798d6b02..f1883239a661 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -145,6 +145,7 @@ BuildPageStateBuffer (
   UINTN RmpPageSize;
   UINTN Index;
   UINTN IndexMax;
+  UINTN PscIndexMax;
 
   // Clear the page state structure
   SetMem (Info, InfoSize, 0);
@@ -153,6 +154,16 @@ BuildPageStateBuffer (
   IndexMax= (InfoSize - sizeof (Info->Header)) / sizeof (Info->Entry[0]);
   NextAddress = EndAddress;
 
+  //
+  // Make the use of the work area as efficient as possible relative to
+  // exiting from the guest to the hypervisor. Maximize the number of entries
+  // that can be processed per exit.
+  //
+  PscIndexMax = (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * 
SNP_PAGE_STATE_MAX_ENTRY;
+  if (PscIndexMax > 0) {
+IndexMax = MIN (IndexMax, PscIndexMax);
+  }
+
   //
   // Populate the page state entry structure
   //
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116534): https://edk2.groups.io/g/devel/message/116534
Mute This Topic: https://groups.io/mt/104810705/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 07/24] MdePkg: Avoid hardcoded value for number of Page State Change entries

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SNP_PAGE_STATE_MAX_ENTRY is based on the number of entries that can
fit in the GHCB shared buffer. As a result, the SNP_PAGE_STATE_CHANGE_INFO
structure maps the full GHCB shared buffer based on the shared buffer size
being 2032 bytes.

Instead of using a hardcoded value for SNP_PAGE_STATE_MAX_ENTRY, use a
build calculated value. Since the SNP_PAGE_STATE_CHANGE_INFO is used as a
mapping, eliminate the hardcoded array size so that the structure can be
used based on any size buffer.

Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Signed-off-by: Tom Lendacky 
---
 MdePkg/Include/Register/Amd/Ghcb.h | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h 
b/MdePkg/Include/Register/Amd/Ghcb.h
index bd7bf986d03f..ae1486b526a6 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -197,13 +197,14 @@ typedef struct {
   UINT32Reserved;
 } SNP_PAGE_STATE_HEADER;
 
-#define SNP_PAGE_STATE_MAX_ENTRY  253
-
 typedef struct {
   SNP_PAGE_STATE_HEADERHeader;
-  SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
+  SNP_PAGE_STATE_ENTRY Entry[];
 } SNP_PAGE_STATE_CHANGE_INFO;
 
+#define SNP_PAGE_STATE_MAX_ENTRY  \
+  ((sizeof (((GHCB *)0)->SharedBuffer) - sizeof (SNP_PAGE_STATE_HEADER)) / 
sizeof (SNP_PAGE_STATE_ENTRY))
+
 //
 // Get APIC IDs
 //
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116532): https://edk2.groups.io/g/devel/message/116532
Mute This Topic: https://groups.io/mt/104810697/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 06/24] OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State Change

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Calculate the amount of memory that can be use to build the Page State
Change data (SNP_PAGE_STATE_CHANGE_INFO) instead of using a hard-coded
size. This allows for changes to the GHCB shared buffer size without
having to make changes to the page state change code.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 12 

 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index 6a11adb06efb..60b176ab14b8 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -133,23 +133,26 @@ BuildPageStateBuffer (
   IN EFI_PHYSICAL_ADDRESSEndAddress,
   IN SEV_SNP_PAGE_STATE  State,
   IN BOOLEAN UseLargeEntry,
-  IN SNP_PAGE_STATE_CHANGE_INFO  *Info
+  IN SNP_PAGE_STATE_CHANGE_INFO  *Info,
+  IN UINTN   InfoSize
   )
 {
   EFI_PHYSICAL_ADDRESS  NextAddress;
   UINTN RmpPageSize;
   UINTN Index;
+  UINTN IndexMax;
 
   // Clear the page state structure
-  SetMem (Info, sizeof (*Info), 0);
+  SetMem (Info, InfoSize, 0);
 
   Index   = 0;
+  IndexMax= (InfoSize - sizeof (Info->Header)) / sizeof (Info->Entry[0]);
   NextAddress = EndAddress;
 
   //
   // Populate the page state entry structure
   //
-  while ((BaseAddress < EndAddress) && (Index < SNP_PAGE_STATE_MAX_ENTRY)) {
+  while ((BaseAddress < EndAddress) && (Index < IndexMax)) {
 //
 // Is this a 2MB aligned page? Check if we can use the Large RMP entry.
 //
@@ -265,7 +268,8 @@ InternalSetPageState (
 EndAddress,
 State,
 UseLargeEntry,
-Info
+Info,
+sizeof (Ghcb->SharedBuffer)
 );
 
 //
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116531): https://edk2.groups.io/g/devel/message/116531
Mute This Topic: https://groups.io/mt/104810694/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 05/24] OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

In prep for follow-on patches, fix an area of the code that does not meet
the uncrustify coding standards.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 27 
+++-
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index 46c6682760d5..6a11adb06efb 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -78,7 +78,9 @@ PvalidateRange (
   IN  BOOLEAN Validate
   )
 {
-  UINTN RmpPageSize, Ret, i;
+  UINTN RmpPageSize;
+  UINTN Index;
+  UINTN Ret;
   EFI_PHYSICAL_ADDRESS  Address;
 
   for ( ; StartIndex <= EndIndex; StartIndex++) {
@@ -96,7 +98,7 @@ PvalidateRange (
 // the RMP entry is 4K and we are validating it as a 2MB.
 //
 if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == 
PvalidatePageSize2MB)) {
-  for (i = 0; i < PAGES_PER_LARGE_ENTRY; i++) {
+  for (Index = 0; Index < PAGES_PER_LARGE_ENTRY; Index++) {
 Ret = AsmPvalidate (PvalidatePageSize4K, Validate, Address);
 if (Ret) {
   break;
@@ -135,18 +137,19 @@ BuildPageStateBuffer (
   )
 {
   EFI_PHYSICAL_ADDRESS  NextAddress;
-  UINTN i, RmpPageSize;
+  UINTN RmpPageSize;
+  UINTN Index;
 
   // Clear the page state structure
   SetMem (Info, sizeof (*Info), 0);
 
-  i   = 0;
+  Index   = 0;
   NextAddress = EndAddress;
 
   //
   // Populate the page state entry structure
   //
-  while ((BaseAddress < EndAddress) && (i < SNP_PAGE_STATE_MAX_ENTRY)) {
+  while ((BaseAddress < EndAddress) && (Index < SNP_PAGE_STATE_MAX_ENTRY)) {
 //
 // Is this a 2MB aligned page? Check if we can use the Large RMP entry.
 //
@@ -160,14 +163,14 @@ BuildPageStateBuffer (
   NextAddress = BaseAddress + EFI_PAGE_SIZE;
 }
 
-Info->Entry[i].GuestFrameNumber = BaseAddress >> EFI_PAGE_SHIFT;
-Info->Entry[i].PageSize = RmpPageSize;
-Info->Entry[i].Operation= MemoryStateToGhcbOp (State);
-Info->Entry[i].CurrentPage  = 0;
-Info->Header.EndEntry   = (UINT16)i;
+Info->Entry[Index].GuestFrameNumber = BaseAddress >> EFI_PAGE_SHIFT;
+Info->Entry[Index].PageSize = RmpPageSize;
+Info->Entry[Index].Operation= MemoryStateToGhcbOp (State);
+Info->Entry[Index].CurrentPage  = 0;
+Info->Header.EndEntry   = (UINT16)Index;
 
 BaseAddress = NextAddress;
-i++;
+Index++;
   }
 
   return NextAddress;
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116530): https://edk2.groups.io/g/devel/message/116530
Mute This Topic: https://groups.io/mt/104810690/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 04/24] OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

If the hypervisor supports retrieval of the vCPU APIC IDs, retrieve
them before any APs are actually started. The APIC IDs can be used
to start the APs for any SEV-SNP guest, but is a requirement for an
SEV-SNP guest that is running under an SVSM.

After retrieving the APIC IDs, save the address of the APIC ID data
structure in a GUIDed HOB.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/PlatformPei/PlatformPei.inf |  1 +
 OvmfPkg/PlatformPei/AmdSev.c| 92 +++-
 2 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index ad52be306560..2206316fec9e 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -45,6 +45,7 @@ [Guids]
   gEfiMemoryTypeInformationGuid
   gFdtHobGuid
   gUefiOvmfPkgPlatformInfoGuid
+  gGhcbApicIdsGuid
 
 [LibraryClasses]
   BaseLib
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index e6b602d79a05..a9de33074a69 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -1,7 +1,7 @@
 /**@file
   Initialize Secure Encrypted Virtualization (SEV) support
 
-  Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.
+  Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -9,6 +9,7 @@
 //
 // The package level header files this module uses
 //
+#include 
 #include 
 #include 
 #include 
@@ -31,6 +32,87 @@ GetHypervisorFeature (
   VOID
   );
 
+/**
+  Retrieve APIC IDs from the hypervisor.
+
+**/
+STATIC
+VOID
+AmdSevSnpGetApicIds (
+  VOID
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  GHCB  *Ghcb;
+  BOOLEAN   InterruptState;
+  UINT64VmgExitStatus;
+  UINT64PageCount;
+  BOOLEAN   PageCountValid;
+  VOID  *ApicIds;
+  RETURN_STATUS Status;
+  UINT64GuidData;
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+  Ghcb= Msr.Ghcb;
+
+  PageCount  = 0;
+  PageCountValid = FALSE;
+
+  CcExitVmgInit (Ghcb, );
+  Ghcb->SaveArea.Rax = PageCount;
+  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, 0, 0);
+  if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
+PageCount  = Ghcb->SaveArea.Rax;
+PageCountValid = TRUE;
+  }
+
+  CcExitVmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  ASSERT (PageCountValid);
+  if ((VmgExitStatus != 0) || !PageCountValid) {
+return;
+  }
+
+  //
+  // Allocate the memory for the APIC IDs
+  //
+  ApicIds = AllocateReservedPages ((UINTN)PageCount);
+  ASSERT (ApicIds != NULL);
+
+  Status = MemEncryptSevClearPageEncMask (
+ 0,
+ (UINTN)ApicIds,
+ (UINTN)PageCount
+ );
+  ASSERT_RETURN_ERROR (Status);
+
+  ZeroMem (ApicIds, EFI_PAGES_TO_SIZE ((UINTN)PageCount));
+
+  PageCountValid = FALSE;
+
+  CcExitVmgInit (Ghcb, );
+  Ghcb->SaveArea.Rax = PageCount;
+  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, (UINTN)ApicIds, 
0);
+  if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax) && (Ghcb->SaveArea.Rax == 
PageCount)) {
+PageCountValid = TRUE;
+  }
+
+  CcExitVmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  ASSERT (PageCountValid);
+  if ((VmgExitStatus != 0) || !PageCountValid) {
+FreePages (ApicIds, (UINTN)PageCount);
+return;
+  }
+
+  GuidData = (UINT64)(UINTN)ApicIds;
+  BuildGuidDataHob (, , sizeof (GuidData));
+}
+
 /**
   Initialize SEV-SNP support if running as an SEV-SNP guest.
 
@@ -78,6 +160,14 @@ AmdSevSnpInitialize (
   }
 }
   }
+
+  //
+  // Retrieve the APIC IDs if the hypervisor supports it. These will be used
+  // to always start APs using SNP AP Create.
+  //
+  if ((HvFeatures & GHCB_HV_FEATURES_APIC_ID_LIST) == 
GHCB_HV_FEATURES_APIC_ID_LIST) {
+AmdSevSnpGetApicIds ();
+  }
 }
 
 /**
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116529): https://edk2.groups.io/g/devel/message/116529
Mute This Topic: https://groups.io/mt/104810685/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 03/24] UefiCpuPkg/MpInitLib: Always use AP Create if GhcbApicIds HOB is present

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Currently, the first time an AP is started for an SEV-SNP guest, it relies
on the VMSA as set by the hypervisor. If the list of APIC IDs has been
retrieved, this is not necessary. The list of APIC IDs will be identified
by a GUIDed HOB. If the GUIDed HOB is present, use the SEV-SNP AP Create
protocol to start the AP for the first time and each time thereafter.

Cc: Gerd Hoffmann 
Cc: Laszlo Ersek 
Cc: Rahul Kumar 
Cc: Ray Ni 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/UefiCpuPkg.dec |  5 +-
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |  1 +
 UefiCpuPkg/Include/Guid/GhcbApicIds.h | 17 +
 UefiCpuPkg/Library/MpInitLib/MpLib.h  | 15 +++-
 UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c| 21 +-
 UefiCpuPkg/Library/MpInitLib/MpLib.c  |  9 ++-
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 78 ++--
 8 files changed, 133 insertions(+), 14 deletions(-)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 571b59b36f0a..c31d8b6736cf 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -2,7 +2,7 @@
 # This Package provides UEFI compatible CPU modules and libraries.
 #
 # Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -91,6 +91,9 @@ [Guids]
   ## Include/Guid/MpInformation2.h
   gMpInformation2HobGuid = { 0x417a7f64, 0xf4e9, 0x4b32, {0x84, 0x6a, 
0x5c, 0xc4, 0xd8, 0x62, 0x18, 0x79 }}
 
+  ## Include/Guid/GhcbApicIds.h
+  gGhcbApicIdsGuid   = { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 
0x10, 0x10, 0x8b, 0x17, 0x80, 0x1b }}
+
 [Protocols]
   ## Include/Protocol/SmmCpuService.h
   gEfiSmmCpuServiceProtocolGuid   = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 
0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 55e46d4a1fad..69950fcd1289 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -68,6 +68,7 @@ [Guids]
   gEfiEventExitBootServicesGuid ## CONSUMES  ## Event
   gEfiEventLegacyBootGuid   ## SOMETIMES_CONSUMES  ## Event
   gEdkiiMicrocodePatchHobGuid   ## SOMETIMES_CONSUMES  ## HOB
+  gGhcbApicIdsGuid  ## SOMETIMES_CONSUMES  ## HOB
 
 [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber## 
CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index bc3d716aa951..22f74a814534 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -76,3 +76,4 @@ [Ppis]
 [Guids]
   gEdkiiS3SmmInitDoneGuid
   gEdkiiMicrocodePatchHobGuid
+  gGhcbApicIdsGuid   ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Include/Guid/GhcbApicIds.h 
b/UefiCpuPkg/Include/Guid/GhcbApicIds.h
new file mode 100644
index ..9d5bfcb0de22
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/GhcbApicIds.h
@@ -0,0 +1,17 @@
+/** @file
+  APIC ID list retrieved for an SEV-ES/SEV-SNP guest via the GHCB.
+
+  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef GHCB_APIC_IDS_H_
+#define GHCB_APIC_IDS_H_
+
+#define GHCB_APIC_IDS_GUID \
+  { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 0x10, 0x10, 0x8b, 0x17, 0x80, 
0x1b }}
+
+extern EFI_GUID  gGhcbApicIdsGuid;
+
+#endif
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index d26035559f22..65e05c4806f5 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -2,7 +2,7 @@
   Common header file for MP Initialize Library.
 
   Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.
-  Copyright (c) 2020, AMD Inc. All rights reserved.
+  Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -924,6 +924,19 @@ SevSnpCreateAP (
   IN INTN ProcessorNumber
   );
 
+/**
+  Determine if the SEV-SNP AP Create protocol should be used.
+
+  @param[in]  CpuMpData  Pointer to CPU MP Data
+
+  @retval TRUE   Use SEV-SNP AP Create protocol
+  @retval FALSE  Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+CanUseSevSnpCreateAP (
+  IN  CPU_MP_DATA  *CpuMpData
+  );
+
 /**
   Get pointer to CPU MP Data structure from GUIDed HOB.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index c83144285b68..0478e92317f1 100644
--- 

[edk2-devel] [PATCH v3 02/24] MdePkg: GHCB APIC ID retrieval support definitions

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When an SVSM is present, starting the APs requires knowledge of the APIC
IDs. Create the definitions required to retrieve and hold the APIC ID
information of all the vCPUs present in the guest.

Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Zhiguang Liu 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 MdePkg/Include/Register/Amd/Ghcb.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h 
b/MdePkg/Include/Register/Amd/Ghcb.h
index dab396f3ede8..bd7bf986d03f 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -4,7 +4,7 @@
   Provides data types allowing an SEV-ES guest to interact with the hypervisor
   using the GHCB protocol.
 
-  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Specification Reference:
@@ -56,6 +56,7 @@
 #define SVM_EXIT_AP_JUMP_TABLE  0x8005ULL
 #define SVM_EXIT_SNP_PAGE_STATE_CHANGE  0x8010ULL
 #define SVM_EXIT_SNP_AP_CREATION0x8013ULL
+#define SVM_EXIT_GET_APIC_IDS   0x8017ULL
 #define SVM_EXIT_HYPERVISOR_FEATURES0x8000FFFDULL
 #define SVM_EXIT_UNSUPPORTED0x8000ULL
 
@@ -170,6 +171,7 @@ typedef union {
 #define GHCB_HV_FEATURES_SNP_AP_CREATE   (GHCB_HV_FEATURES_SNP 
| BIT1)
 #define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION
(GHCB_HV_FEATURES_SNP_AP_CREATE | BIT2)
 #define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION_TIMER  
(GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION | BIT3)
+#define GHCB_HV_FEATURES_APIC_ID_LISTBIT4
 
 //
 // SNP Page State Change.
@@ -202,6 +204,14 @@ typedef struct {
   SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
 } SNP_PAGE_STATE_CHANGE_INFO;
 
+//
+// Get APIC IDs
+//
+typedef struct {
+  UINT32NumEntries;
+  UINT32ApicIds[];
+} GHCB_APIC_IDS;
+
 //
 // SEV-ES save area mapping structures used for SEV-SNP AP Creation.
 // Only the fields required to be set to a non-zero value are defined.
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116527): https://edk2.groups.io/g/devel/message/116527
Mute This Topic: https://groups.io/mt/104810677/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 01/24] OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()

2024-03-08 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The AsmRmpAdjust() function returns a UINT32, however in SevSnpIsVmpl0()
the return value is checked with EFI_ERROR() when it should just be
compared to 0. Fix the error check.

Cc: Ard Biesheuvel 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Michael Roth 
Cc: Min Xu 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
index 7797febb8ac6..be43a44e4e1d 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -31,8 +31,8 @@ SevSnpIsVmpl0 (
   VOID
   )
 {
-  UINT64  Rdx;
-  EFI_STATUS  Status;
+  UINT64  Rdx;
+  UINT32  Status;
 
   //
   // There is no straightforward way to query the current VMPL level.
@@ -44,7 +44,7 @@ SevSnpIsVmpl0 (
   Rdx = 1;
 
   Status = AsmRmpAdjust ((UINT64)gVmpl0Data, 0, Rdx);
-  if (EFI_ERROR (Status)) {
+  if (Status != 0) {
 return FALSE;
   }
 
-- 
2.43.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116526): https://edk2.groups.io/g/devel/message/116526
Mute This Topic: https://groups.io/mt/104810674/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v3 00/24] Provide SEV-SNP support for running under an SVSM

2024-03-08 Thread Lendacky, Thomas via groups.io


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new AmdSvsmLib library that is used by MpInitLib.
The edk2-platforms repo requires updates/patches to add the new library
requirement. To accomodate that, this series could be split between:

patch number 12:
  UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an SVSM

and patch number 13:
  UefiPayloadPkg: Prepare UefiPayloadPkg to use the AmdSvsmLib library

The updates to edk2-platforms can be applied at the split.

This series introduces support to run OVMF under an SVSM. It consists
of:
  - Retrieving the list of vCPU APIC IDs and starting up all APs without
performing a broadcast SIPI
  - Reorganizing the page state change support to not directly use the
GHCB buffer since an SVSM will use the calling area buffer, instead
  - Detecting the presence of an SVSM
  - When not running at VMPL0, invoking the SVSM for page validation and
VMSA page creation/deletion
  - Detecting and allowing OVMF to run in a VMPL other than 0 when an
SVSM is present

The series is based off of commit:

  e60529df58e4 ("UefiPayloadPkg: Make Dsc accomodative of other archs")

[1] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf
[2] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf

Cc: Anatol Belski 
Cc: Anthony Perard 
Cc: Ard Biesheuvel 
Cc: Corvin Köhne 
Cc: Erdem Aktas 
Cc: Gerd Hoffmann 
Cc: Gua Guo 
Cc: Guo Dong 
Cc: James Lu 
Cc: Jianyong Wu 
Cc: Jiewen Yao 
Cc: Laszlo Ersek 
Cc: Liming Gao 
Cc: Michael D Kinney 
Cc: Michael Roth 
Cc: Min Xu 
Cc: Rahul Kumar 
Cc: Ray Ni 
Cc: Rebecca Cran 
Cc: Sean Rhodes 
Cc: Zhiguang Liu 

---

Changes in v3:
- Renamed CcSvsmLib to a more AMD-specific AmdSvsmLib with corresponding
  function name changes
- Moved the GHCB APIC ID list GUID definition from MdePkg to UefiCpuPkg
  and change the name from gEfiApicIdsGuid to gGhcbApicIdsGuid
- Separated the OvmfPkg changes for the AmdSvsmLib into two patches:
  - First patch adds usage of the AmdSvsmLib NULL library
  - Second patch adds the OVMF AmdSvsmLib implementation
- Updated the commit message for the OVMF AmdSvsmLib implementation to
  indicate that the base functionality for PVALIDATE and RMPADJUST was
  copied from the original locations in prep for converting those sites
  to using the library API.

Changes in v2:
- Move the APIC IDs retrieval support to the beginning of the patch series
- Use a GUIDed HOB to hold the APIC ID list instead of a PCD
- Split up Page State Change reorganization into multiple patches
- Created CcSvsmLib library instead of extending CcExitLib
- This will require a corresponding update to edk2-platform DSC files
- Removed Ray Ni's Acked-by since it is not a minor change
- Variable name changes and other misc changes

Tom Lendacky (24):
  OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()
  MdePkg: GHCB APIC ID retrieval support definitions
  UefiCpuPkg/MpInitLib: Always use AP Create if GhcbApicIds HOB is
present
  OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
  OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors
  OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State
Change
  MdePkg: Avoid hardcoded value for number of Page State Change entries
  OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support
  OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency
  MdePkg/Register/Amd: Define the SVSM related information
  MdePkg/BaseLib: Add a new VMGEXIT instruction invocation for SVSM
  UefiCpuPkg/AmdSvsmLib: Create the AmdSvsmLib library to support an
SVSM
  UefiPayloadPkg: Prepare UefiPayloadPkg to use the 

Re: [edk2-devel] GuestPhysAddrSize questions

2024-03-04 Thread Lendacky, Thomas via groups.io

On 3/4/24 07:09, Gerd Hoffmann wrote:

   Hi,


23:16 GuestPhysAddrSize Maximum guest physical address size in bits.
This number applies only to guests using nested
paging. When this field is zero, refer to the
PhysAddrSize field for the maximum guest
physical address size. See “Secure Virtual
Machine” in APM Volume 2.



I believe the main purpose of GuestPhysAddrSize was for software use (for
nested virtualization) and that the hardware itself has always returned zero
for that value. So you should be able to use that field. Adding @Paolo for
his thoughts.


Posted patches for kernel
https://lore.kernel.org/kvm/20240301101410.356007-1-kra...@redhat.com/
and qemu
https://lore.kernel.org/kvm/20240301101713.356759-1-kra...@redhat.com/
(sorry forgot to Cc you).

Reviewers mentioned this is meant for nested guests, i.e. (if I
understand this correctly) the l0 hypervisor can use that to tell
the l1 hypervisor what the l2 guest phys-bits should be.

Is this nested virtualization use documented somewhere?  Tried to
search for GuestPhysAddrSize or Fn8000_0008_EAX in APM Volume 2,
found nothing.


Right, and I don't think you'll see anything added to the APM that will 
state how it can be used by software. The APM is an architectural 
definition and won't talk about hypervisors and using nested paging, etc.




Is there any case where the phys-bits limits for an l1 guest and
l2 guest would be different?


I haven't really thought about this before and all the implications that 
may or may not be in play, so I don't think I can really answer that.


Thanks,
Tom



thanks & take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116332): https://edk2.groups.io/g/devel/message/116332
Mute This Topic: https://groups.io/mt/104510523/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 09/10] OvmfPkg/ResetVector: leave SEV VC handler installed longer

2024-02-29 Thread Lendacky, Thomas via groups.io

On 2/22/24 05:54, Gerd Hoffmann wrote:

When running in SEV mode keep the VC handler installed.
Add a function to uninstall it later.

This allows using the cpuid instruction in SetCr3ForPageTables64,
which is needed to check for la57 & 1G page support.

Signed-off-by: Gerd Hoffmann 


Looks good, just one minor comment below.

Reviewed-by: Tom Lendacky 


---
  OvmfPkg/ResetVector/Ia32/AmdSev.asm   | 12 ++--
  OvmfPkg/ResetVector/Ia32/PageTables64.asm |  1 +
  OvmfPkg/ResetVector/Main.asm  |  4 
  3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm 
b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
index ed94f1dc668f..9063ce1080d3 100644
--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -320,9 +320,9 @@ NoSevEsVcHlt:
  NoSevPass:
  xor   eax, eax
  
-SevExit:

  ;
-; Clear exception handlers and stack
+; When NOT running in SEV mode: clear exception handlers and stack here.
+; Otherwise: SevClearVcHandlerAndStack must be called later.
  ;
  push  eax
  mov   eax, ADDR_OF(IdtrClear)
@@ -330,8 +330,16 @@ SevExit:
  pop   eax
  mov   esp, 0
  
+SevExit:

  OneTimeCallRet CheckSevFeatures
  
+SevClearVcHandlerAndStack:

+; Clear exception handlers and stack
+mov   eax, ADDR_OF(IdtrClear)
+lidt  [cs:eax]
+mov   esp, 0
+OneTimeCallRet SevClearVcHandlerAndStack
+
  ; Start of #VC exception handling routines
  ;
  
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm

index ada3dc0ffbe0..6e2063430802 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -250,6 +250,7 @@ SevInit:
  CreatePageTables4Level edx
  ; Clear the C-bit from the GHCB page if the SEV-ES is enabled.
  OneTimeCall   SevClearPageEncMaskForGhcbPage
+OneTimeCall   SevClearVcHandlerAndStack
  jmp SetCr3
  
  TdxBspInit:

diff --git a/OvmfPkg/ResetVector/Main.asm b/OvmfPkg/ResetVector/Main.asm
index 46cfa87c4c0a..88b25db3bc9e 100644
--- a/OvmfPkg/ResetVector/Main.asm
+++ b/OvmfPkg/ResetVector/Main.asm
@@ -80,7 +80,11 @@ SearchBfv:
  ; Set the OVMF/SEV work area as appropriate.
  ;
  OneTimeCall CheckSevFeatures
+cmp byte[WORK_AREA_GUEST_TYPE], 1
+jnz NoSevIa32
+OneTimeCall SevClearVcHandlerAndStack


I think it is safe to invoke SevClearVcHandlerAndStack no matter what if 
you want to avoid the cmp and jnz instructions.


Thanks,
Tom

  
+NoSevIa32:

  ;
  ; Restore initial EAX value into the EAX register
  ;



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116176): https://edk2.groups.io/g/devel/message/116176
Mute This Topic: https://groups.io/mt/104506799/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM

2024-02-29 Thread Lendacky, Thomas via groups.io

On 2/29/24 08:06, Yao, Jiewen wrote:

Below:


-Original Message-
From: Tom Lendacky 
Sent: Thursday, February 29, 2024 12:20 AM
To: Yao, Jiewen ; devel@edk2.groups.io
Cc: Ard Biesheuvel ; Aktas, Erdem
; Gerd Hoffmann ; Laszlo Ersek
; Liming Gao ; Kinney, Michael
D ; Xu, Min M ; Liu,
Zhiguang ; Kumar, Rahul R ;
Ni, Ray ; Michael Roth 
Subject: Re: [PATCH v2 00/23] Provide SEV-SNP support for running under an
SVSM

On 2/28/24 00:14, Yao, Jiewen wrote:

Some feedback:

1) 0002-MdePkg-GHCB-APIC-ID-retrieval-support-definitions

MdePkg only contains the definition in the standard.

Question: Is EFI_APIC_IDS_GUID definition in some AMD/SVSM specification?


The structure is documented in the GHCB specification, but the GUID is not.

Is the request to move the GUID to someplace other than MdePkg?


[Jiewen] Right. If the GUID is NOT in GHCB spec, then it should be in other 
place, such as OvmfPkg.


Sounds good. I'll move to the UefiCpuPkg since MpInitLib will be using it.








2) 0012-UefiCpuPkg-CcSvsmLib-Create-the-CcSvsmLib-library-to-support-an-

SVSM


I am not sure the position of SVSM.
If the SVSM interface is AMD specific, the it should be AmdSvsmLib.


I believe TDX is also looking at the SVSM for TDX partitioning, but I'm
not certain of that.


If the SVSM interface is generic, then we should define everything in a generic

way.


It is very confusing to mix a generic CcSvsm lib with AMD specific

.

I can certainly change the name to be AMD specific fow now. It can always
be changed to something else later if need be, much like VmgExitLib was
changed to CcExitLib.


[Jiewen] Yes, Intel is planning for SVSM. But it is NOT ready yet.
It is hard for me to discuss it now.

Maybe, please help me understand:
Is CcSvsmLib a generic library / common protocol between OVMF and Coconut-SVSM? 
- Option 1
Or is CcSvsmLib an implementation specific library, and the current API cannot 
be shared with Intel TDX in future? - Option 2

I notice that some API is for option 1 - CcSvsmIsSvsmPresent().
But some API is for option 2 - CcSvsmSnpGetVmpl(), CcSvsmSnpGetCaa(), 
CcSvsmSnpPvalidate(), CcSvsmSnpVmsaRmpAdjust().

How do you plan if TDX need to support SVSM later?
How do you plan if we need to add some generic interaction between OVMF and 
coconut-SVSM, such as vTPM?


There are definitely some things that will be common, 
CcSvsmIsSvsmPresent() and CcSvsmSnpGetCaa(), and some things that will be 
SNP or TDX specific. For example, the concept of turning a page into a 
VMSA page or how the SVSM will be invoked will be different.


For now, I'll create an AMD specific library and then when TDX is ready to 
support an SVSM we can look to see how or what needs to be changed. It 
could be that they need to remain separate if there is not enough in common.


Thanks,
Tom







Thanks,
Tom




Thank you
Yao, Jiewen


-Original Message-
From: Tom Lendacky 
Sent: Friday, February 23, 2024 1:30 AM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel ; Aktas, Erdem
; Gerd Hoffmann ; Yao,

Jiewen

; Laszlo Ersek ; Liming Gao
; Kinney, Michael D

;

Xu, Min M ; Liu, Zhiguang ;
Kumar, Rahul R ; Ni, Ray ;

Michael

Roth 
Subject: [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs

that

it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new CcSvsmLib library that is used by MpInitLib.
This requires an update to the edk2-platform DSC files to add the new
library. The edk2-platform change would be needed after patch 12, but
before patch 15.

This series introduces support to run OVMF under an SVSM. It consists
of:
- Retrieving the list of vCPU APIC IDs and starting up all APs without
  performing a broadcast SIPI
- Reorganizing the page state change support to not 

Re: [edk2-devel] [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM

2024-02-28 Thread Lendacky, Thomas via groups.io

On 2/28/24 00:14, Yao, Jiewen wrote:

Some feedback:

1) 0002-MdePkg-GHCB-APIC-ID-retrieval-support-definitions

MdePkg only contains the definition in the standard.

Question: Is EFI_APIC_IDS_GUID definition in some AMD/SVSM specification?


The structure is documented in the GHCB specification, but the GUID is not.

Is the request to move the GUID to someplace other than MdePkg?



2) 0012-UefiCpuPkg-CcSvsmLib-Create-the-CcSvsmLib-library-to-support-an-SVSM

I am not sure the position of SVSM.
If the SVSM interface is AMD specific, the it should be AmdSvsmLib.


I believe TDX is also looking at the SVSM for TDX partitioning, but I'm 
not certain of that.



If the SVSM interface is generic, then we should define everything in a generic 
way.

It is very confusing to mix a generic CcSvsm lib with AMD specific 
.


I can certainly change the name to be AMD specific fow now. It can always 
be changed to something else later if need be, much like VmgExitLib was 
changed to CcExitLib.


Thanks,
Tom




Thank you
Yao, Jiewen


-Original Message-
From: Tom Lendacky 
Sent: Friday, February 23, 2024 1:30 AM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel ; Aktas, Erdem
; Gerd Hoffmann ; Yao, Jiewen
; Laszlo Ersek ; Liming Gao
; Kinney, Michael D ;
Xu, Min M ; Liu, Zhiguang ;
Kumar, Rahul R ; Ni, Ray ; Michael
Roth 
Subject: [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new CcSvsmLib library that is used by MpInitLib.
This requires an update to the edk2-platform DSC files to add the new
library. The edk2-platform change would be needed after patch 12, but
before patch 15.

This series introduces support to run OVMF under an SVSM. It consists
of:
   - Retrieving the list of vCPU APIC IDs and starting up all APs without
 performing a broadcast SIPI
   - Reorganizing the page state change support to not directly use the
 GHCB buffer since an SVSM will use the calling area buffer, instead
   - Detecting the presence of an SVSM
   - When not running at VMPL0, invoking the SVSM for page validation and
 VMSA page creation/deletion
   - Detecting and allowing OVMF to run in a VMPL other than 0 when an
 SVSM is present

The series is based off of commit:

   2ca8d5597443 ("UefiCpuPkg/PiSmmCpuDxeSmm: Check BspIndex first before
lock cmpxchg")

[1] https://www.amd.com/content/dam/amd/en/documents/epyc-technical-
docs/specifications/58019.pdf
[2] https://www.amd.com/content/dam/amd/en/documents/epyc-technical-
docs/specifications/56421.pdf

---

Changes in v2:
- Move the APIC IDs retrieval support to the beginning of the patch series
 - Use a GUIDed HOB to hold the APIC ID list instead of a PCD
- Split up Page State Change reorganization into multiple patches
- Created CcSvsmLib library instead of extending CcExitLib
 - This will require a corresponding update to edk2-platform DSC files
 - Removed Ray Ni's Acked-by since it is not a minor change
- Variable name changes and other misc changes

Tom Lendacky (23):
   OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()
   MdePkg: GHCB APIC ID retrieval support definitions
   OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
   UefiCpuPkg/MpInitLib: Always use AP Create if PcdSevSnpApicIds is set
   OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors
   OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State
 Change
   MdePkg: Avoid hardcoded value for number of Page State Change entries
   OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support
   OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency
   MdePkg/Register/Amd: Define the SVSM related information
   MdePkg/BaseLib: Add 

Re: [edk2-devel] [PATCH v2 18/23] OvmfPkg/CcSvsmLib: Add support for the SVSM_CORE_PVALIDATE call

2024-02-28 Thread Lendacky, Thomas via groups.io

On 2/28/24 02:50, Gerd Hoffmann wrote:

   Hi,


+// Clear the buffer in prep for creating all new entries
+SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0);


Minor nit: There is a ZeroMem() for this purpose.


I use SetMem() in a few places, I'll change them over to ZeroMem().

Thanks,
Tom



Acked-by: Gerd Hoffmann 

take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116120): https://edk2.groups.io/g/devel/message/116120
Mute This Topic: https://groups.io/mt/104512972/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v2 14/23] Ovmfpkg/CcSvsmLib: Create CcSvsmLib to handle SVSM related services

2024-02-28 Thread Lendacky, Thomas via groups.io

On 2/28/24 02:40, Gerd Hoffmann wrote:

+/**
+  Perform a native PVALIDATE operation for the page ranges specified.
+
+  Validate or rescind the validation of the specified pages.
+
+  @param[in]   Info   Pointer to a page state change structure
+
+**/
+STATIC
+VOID
+BasePvalidate (
+  IN  SNP_PAGE_STATE_CHANGE_INFO  *Info
+  )


This is not mentioned in the commit message.

Looks like you are moving or copying code from BaseMemEncryptSevLib.

Moving code is best done with a patch doing the move only, without other
functional changes.  If that can't be done easily this should explained
in the commit message.


I can leave this as unsupported in this patch and then when switching over 
to using the functions in patch #16, move the code at that time.


For the VMSA update, that isn't as easy because of the interaction between 
UefiCpuPkg (MpInitLib) and OvmfPkg and requires two separate patches, 
which would cause bisection breakage.


Or I could keep this all here and expand the commit message to indicate 
that the base support is being implemented based off of the existing support.


Thoughts?

Thanks,
Tom



take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116119): https://edk2.groups.io/g/devel/message/116119
Mute This Topic: https://groups.io/mt/104512963/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v2 07/23] MdePkg: Avoid hardcoded value for number of Page State Change entries

2024-02-27 Thread Lendacky, Thomas via groups.io

On 2/27/24 04:18, Gerd Hoffmann wrote:

On Thu, Feb 22, 2024 at 11:29:46AM -0600, Tom Lendacky wrote:

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SNP_PAGE_STATE_MAX_ENTRY is based on the number of entries that can
fit in the GHCB shared buffer. As a result, the SNP_PAGE_STATE_CHANGE_INFO
structure maps the full GHCB shared buffer based on the shared buffer size
being 2032 bytes.

Instead of using a hardcoded value for SNP_PAGE_STATE_MAX_ENTRY, use a
build calculated value. Since the SNP_PAGE_STATE_CHANGE_INFO is used as a
mapping, eliminate the hardcoded array size so that the structure can be
used based on any size buffer.

Signed-off-by: Tom Lendacky 
---
  MdePkg/Include/Register/Amd/Ghcb.h | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h 
b/MdePkg/Include/Register/Amd/Ghcb.h
index 432d67e3e223..0cdc00627472 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -197,13 +197,14 @@ typedef struct {
UINT32Reserved;
  } SNP_PAGE_STATE_HEADER;
  
-#define SNP_PAGE_STATE_MAX_ENTRY  253

-
  typedef struct {
SNP_PAGE_STATE_HEADERHeader;
-  SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
+  SNP_PAGE_STATE_ENTRY Entry[];
  } SNP_PAGE_STATE_CHANGE_INFO;


Good.


+#define SNP_PAGE_STATE_MAX_ENTRY  \
+  ((sizeof (((GHCB *)0)->SharedBuffer) - sizeof (SNP_PAGE_STATE_HEADER)) / 
sizeof (SNP_PAGE_STATE_ENTRY))


Can be dropped I think, after applying patch #6 BaseMemEncryptSevLib
does not use SNP_PAGE_STATE_MAX_ENTRY any more.


It gets used again in patch #9 for the exit optimization support.

Thanks,
Tom



take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116050): https://edk2.groups.io/g/devel/message/116050
Mute This Topic: https://groups.io/mt/104512946/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 23/23] OvmfPkg/BaseMemEncryptLib: Check for presence of an SVSM when not at VMPL0

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Currently, an SEV-SNP guest will terminate if it is not running at VMPL0.
The requirement for running at VMPL0 is removed if an SVSM is present.

Update the current VMPL0 check to additionally check for the presence of
an SVSM is the guest is not running at VMPL0.

Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c | 9 
++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
index ca279d77274b..f2d9f7cf2fea 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "SnpPageStateChange.h"
 
@@ -74,10 +75,12 @@ MemEncryptSevSnpPreValidateSystemRam (
 
   //
   // The page state change uses the PVALIDATE instruction. The instruction
-  // can be run on VMPL-0 only. If its not VMPL-0 guest then terminate
-  // the boot.
+  // can be run at VMPL-0 only. If its not a VMPL-0 guest, then an SVSM must
+  // be present to perform the operation on behalf of the guest. If the guest
+  // is not running at VMPL-0 and an SVSM is not present, then terminate the
+  // boot.
   //
-  if (!SevSnpIsVmpl0 ()) {
+  if (!SevSnpIsVmpl0 () && !CcSvsmIsSvsmPresent ()) {
 SnpPageStateFailureTerminate ();
   }
 
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115858): https://edk2.groups.io/g/devel/message/115858
Mute This Topic: https://groups.io/mt/104512987/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 22/23] Ovmfpkg/CcExitLib: Provide SVSM discovery support

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SVSM specification documents an alternative method of discovery for
the SVSM using a reserved CPUID bit and a reserved MSR.

For the CPUID support, the #VC handler of an SEV-SNP guest should modify
the returned value in the EAX register for the 0x801f CPUID function
by setting bit 28 when an SVSM is present.

For the MSR support, new reserved MSR 0xc001f000 has been defined. A #VC
should be generated when accessing this MSR. The #VC handler is expected
to ignore writes to this MSR and return the physical calling area address
(CAA) on reads of this MSR.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/CcExitLib/CcExitLib.inf |  3 +-
 OvmfPkg/Library/CcExitLib/SecCcExitLib.inf  |  3 +-
 OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 29 ++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/Library/CcExitLib/CcExitLib.inf 
b/OvmfPkg/Library/CcExitLib/CcExitLib.inf
index bc75cd5f5a04..692143acd9ad 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitLib.inf
+++ b/OvmfPkg/Library/CcExitLib/CcExitLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  CcExitLib Library.
 #
-#  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #  Copyright (C) 2020 - 2022, Intel Corporation. All rights reserved.
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -41,6 +41,7 @@ [LibraryClasses]
   DebugLib
   LocalApicLib
   MemEncryptSevLib
+  CcSvsmLib
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase
diff --git a/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf 
b/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
index 811269dd2c06..6778c1af6516 100644
--- a/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
+++ b/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  VMGEXIT Support Library.
 #
-#  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -41,6 +41,7 @@ [LibraryClasses]
   LocalApicLib
   MemEncryptSevLib
   PcdLib
+  CcSvsmLib
 
 [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c 
b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
index 0fc30f7bc4f6..edb4b57655d4 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
@@ -1,7 +1,7 @@
 /** @file
   X64 #VC Exception Handler functon.
 
-  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -713,10 +714,29 @@ MsrExit (
   IN CC_INSTRUCTION_DATA *InstructionData
   )
 {
-  UINT64  ExitInfo1, Status;
+  MSR_SVSM_CAA_REGISTER  Msr;
+  UINT64 ExitInfo1;
+  UINT64 Status;
 
   ExitInfo1 = 0;
 
+  //
+  // The SVSM CAA MSR is a software implemented MSR and not supported
+  // by the hardware, handle it directly.
+  //
+  if (Regs->Rax == MSR_SVSM_CAA) {
+// Writes to the SVSM CAA MSR are ignored
+if (*(InstructionData->OpCodes + 1) == 0x30) {
+  return 0;
+}
+
+Msr.Uint64 = CcSvsmSnpGetCaa ();
+Regs->Rax  = Msr.Bits.Lower32Bits;
+Regs->Rdx  = Msr.Bits.Upper32Bits;
+
+return 0;
+  }
+
   switch (*(InstructionData->OpCodes + 1)) {
 case 0x30: // WRMSR
   ExitInfo1  = 1;
@@ -1388,6 +1408,11 @@ GetCpuidFw (
 *Ebx = (*Ebx & 0xFF00) | (Ebx2 & 0x00FF);
 /* node ID */
 *Ecx = (*Ecx & 0xFF00) | (Ecx2 & 0x00FF);
+  } else if (EaxIn == 0x801F) {
+/* Set the SVSM feature bit if running under an SVSM */
+if (CcSvsmIsSvsmPresent ()) {
+  *Eax |= BIT28;
+}
   }
 
 Out:
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115857): https://edk2.groups.io/g/devel/message/115857
Mute This Topic: https://groups.io/mt/104512981/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 21/23] UefiCpuPkg/MpInitLib: AP creation support under an SVSM

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When running under an SVSM, the VMPL level of the APs that are started
must match the VMPL level provided by the SVSM. Additionally, each AP
must have a Calling Area for use with the SVSM protocol. Update the AP
creation to properly support running under an SVSM.

Acked-by: Ray Ni 
Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 28 +---
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index bb4a52b25cd2..681a47669a47 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -44,7 +44,8 @@ SevSnpPerformApAction (
 
   if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
 //
-// Turn the page into a recognized VMSA page.
+// Turn the page into a recognized VMSA page. When an SVSM is present
+// the page following the VMSA is the Calling Area page.
 //
 VmsaStatus = CcSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
 if (EFI_ERROR (VmsaStatus)) {
@@ -56,6 +57,7 @@ SevSnpPerformApAction (
   }
 
   ExitInfo1  = (UINT64)ApicId << 32;
+  ExitInfo1 |= (UINT64)SaveArea->Vmpl << 16;
   ExitInfo1 |= Action;
   ExitInfo2  = (UINT64)(UINTN)SaveArea;
 
@@ -87,8 +89,9 @@ SevSnpPerformApAction (
 
   if (Action == SVM_VMGEXIT_SNP_AP_DESTROY) {
 //
-// Make the current VMSA not runnable and accessible to be
-// reprogrammed.
+// Make the current VMSA not runnable and accessible to be reprogrammed.
+// When an SVSM is present the page following the VMSA is the Calling Area
+// page.
 //
 VmsaStatus = CcSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
 if (EFI_ERROR (VmsaStatus)) {
@@ -116,6 +119,7 @@ SevSnpCreateSaveArea (
   UINT32  ApicId
   )
 {
+  UINTN PageCount;
   UINT8 *Pages;
   SEV_ES_SAVE_AREA  *SaveArea;
   IA32_CR0  ApCr0;
@@ -125,13 +129,19 @@ SevSnpCreateSaveArea (
   UINTN StartIp;
   UINT8 SipiVector;
 
+  //
+  // When running under an SVSM, a Calling Area page is also needed and is
+  // always the page following the VMSA.
+  //
+  PageCount = CcSvsmIsSvsmPresent () ? 2 : 1;
+
   if (CpuData->SevEsSaveArea == NULL) {
 //
 // Allocate a page for the SEV-ES Save Area and initialize it. Due to AMD
 // erratum #1467 (VMSA cannot be on a 2MB boundary), allocate an extra page
 // to choose from to work around the issue.
 //
-Pages = AllocateReservedPages (2);
+Pages = AllocateReservedPages (PageCount + 1);
 if (!Pages) {
   return;
 }
@@ -140,12 +150,12 @@ SevSnpCreateSaveArea (
 // Since page allocation works by allocating downward in the address space,
 // try to always free the first (lower address) page to limit possible 
holes
 // in the memory map. So, if the address of the second page is 2MB aligned,
-// then use the first page and free the second page. Otherwise, free the
+// then use the first page and free the last page. Otherwise, free the
 // first page and use the second page.
 //
 if (_IS_ALIGNED (Pages + EFI_PAGE_SIZE, SIZE_2MB)) {
   SaveArea = (SEV_ES_SAVE_AREA *)Pages;
-  FreePages (Pages + EFI_PAGE_SIZE, 1);
+  FreePages (Pages + (EFI_PAGE_SIZE * PageCount), 1);
 } else {
   SaveArea = (SEV_ES_SAVE_AREA *)(Pages + EFI_PAGE_SIZE);
   FreePages (Pages, 1);
@@ -163,7 +173,7 @@ SevSnpCreateSaveArea (
 }
   }
 
-  ZeroMem (SaveArea, EFI_PAGE_SIZE);
+  ZeroMem (SaveArea, EFI_PAGE_SIZE * PageCount);
 
   //
   // Propogate the CR0.NW and CR0.CD setting to the AP
@@ -239,10 +249,10 @@ SevSnpCreateSaveArea (
 
   //
   // Set the SEV-SNP specific fields for the save area:
-  //   VMPL - always VMPL0
+  //   VMPL - based on current mode
   //   SEV_FEATURES - equivalent to the SEV_STATUS MSR right shifted 2 bits
   //
-  SaveArea->Vmpl= 0;
+  SaveArea->Vmpl= CcSvsmSnpGetVmpl ();
   SaveArea->SevFeatures = AsmReadMsr64 (MSR_SEV_STATUS) >> 2;
 
   SevSnpPerformApAction (SaveArea, ApicId, SVM_VMGEXIT_SNP_AP_CREATE);
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115856): https://edk2.groups.io/g/devel/message/115856
Mute This Topic: https://groups.io/mt/104512980/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 20/23] OvmfPkg/CcSvsmLib: Add support for the SVSM create/delete vCPU calls

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to alter the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. When
an SVSM is present, use the SVSM_CORE_CREATE_VCPU and SVSM_CORE_DELTE_VCPU
calls to add or remove the VMSA attribute on a page instead of issuing
the RMPADJUST instruction directly.

Implement the CcSvsmSnpVmsaRmpAdjust() API to perform the proper operation
to update the VMSA attribute.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c | 54 +++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c 
b/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
index 017ca715cee5..97fe09aa7329 100644
--- a/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
+++ b/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
@@ -377,6 +377,57 @@ CcSvsmSnpPvalidate (
   CcSvsmIsSvsmPresent () ? SvsmPvalidate (Info) : BasePvalidate (Info);
 }
 
+/**
+  Perform an RMPADJUST operation to alter the VMSA setting of a page.
+
+  Add or remove the VMSA attribute for a page.
+
+  @param[in]   Vmsa   Pointer to an SEV-ES save area page
+  @param[in]   ApicId APIC ID associated with the VMSA
+  @param[in]   SetVmsaBoolean indicator as to whether to set or
+  or clear the VMSA setting for the page
+
+  @retval  EFI_SUCCESSRMPADJUST operation successful
+  @retval  EFI_UNSUPPORTEDOperation is not supported
+  @retval  EFI_INVALID_PARAMETER  RMPADJUST operation failed, an invalid
+  parameter was supplied
+
+**/
+STATIC
+EFI_STATUS
+SvsmVmsaRmpAdjust (
+  IN SEV_ES_SAVE_AREA  *Vmsa,
+  IN UINT32ApicId,
+  IN BOOLEAN   SetVmsa
+  )
+{
+  SVSM_CALL_DATA  SvsmCallData;
+  SVSM_FUNCTION   Function;
+  UINTN   Ret;
+
+  SvsmCallData.Caa = (SVSM_CAA *)CcSvsmSnpGetCaa ();
+
+  Function.Id.Protocol = 0;
+
+  if (SetVmsa) {
+Function.Id.CallId = 2;
+
+SvsmCallData.RaxIn = Function.Uint64;
+SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+SvsmCallData.RdxIn = (UINT64)(UINTN)Vmsa + SIZE_4KB;
+SvsmCallData.R8In  = ApicId;
+  } else {
+Function.Id.CallId = 3;
+
+SvsmCallData.RaxIn = Function.Uint64;
+SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+  }
+
+  Ret = SvsmMsrProtocol ();
+
+  return (Ret == 0) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+}
+
 /**
   Perform a native RMPADJUST operation to alter the VMSA setting of a page.
 
@@ -444,5 +495,6 @@ CcSvsmSnpVmsaRmpAdjust (
   IN BOOLEAN   SetVmsa
   )
 {
-  return BaseVmsaRmpAdjust (Vmsa, SetVmsa);
+  return CcSvsmIsSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa)
+: BaseVmsaRmpAdjust (Vmsa, SetVmsa);
 }
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115855): https://edk2.groups.io/g/devel/message/115855
Mute This Topic: https://groups.io/mt/104512977/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 19/23] OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Similar to the Page State Change optimization added previously, also take
into account the possiblity of using the SVSM for PVALIDATE instructions.
Conditionally adjust the maximum number of entries based on how many
entries the SVSM calling area can support.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 7 
+++
 1 file changed, 7 insertions(+)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index 4e1225d12797..7060cd61b21c 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -18,6 +18,7 @@
 
 #include 
 #include 
+#include 
 
 #include "SnpPageStateChange.h"
 
@@ -78,6 +79,7 @@ BuildPageStateBuffer (
   UINTN Index;
   UINTN IndexMax;
   UINTN PscIndexMax;
+  UINTN SvsmIndexMax;
 
   // Clear the page state structure
   SetMem (Info, InfoSize, 0);
@@ -96,6 +98,11 @@ BuildPageStateBuffer (
 IndexMax = MIN (IndexMax, PscIndexMax);
   }
 
+  SvsmIndexMax = (IndexMax / SVSM_PVALIDATE_MAX_ENTRY) * 
SVSM_PVALIDATE_MAX_ENTRY;
+  if (SvsmIndexMax > 0) {
+IndexMax = MIN (IndexMax, SvsmIndexMax);
+  }
+
   //
   // Populate the page state entry structure
   //
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115854): https://edk2.groups.io/g/devel/message/115854
Mute This Topic: https://groups.io/mt/104512975/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 18/23] OvmfPkg/CcSvsmLib: Add support for the SVSM_CORE_PVALIDATE call

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The PVALIDATE instruction can only be performed at VMPL0. An SVSM will
be present when running at VMPL1 or higher.

When an SVSM is present, use the SVSM_CORE_PVALIDATE call to perform
memory validation instead of issuing the PVALIDATE instruction directly.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c | 183 +++-
 1 file changed, 182 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c 
b/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
index f45ae472783c..017ca715cee5 100644
--- a/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
+++ b/OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c
@@ -8,6 +8,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +44,78 @@ SnpTerminate (
   CpuDeadLoop ();
 }
 
+/**
+  Issue an SVSM request.
+
+  Invokes the SVSM to process a request on behalf of the guest.
+
+  @param[in,out]  SvsmCallData  Pointer to the SVSM call data
+
+  @return   Contents of RAX upon return from VMGEXIT
+**/
+STATIC
+UINTN
+SvsmMsrProtocol (
+  IN OUT SVSM_CALL_DATA  *SvsmCallData
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  UINT64CurrentMsr;
+  UINT8 Pending;
+  BOOLEAN   InterruptState;
+  UINTN Ret;
+
+  do {
+//
+// Be sure that an interrupt can't cause a #VC while the GHCB MSR protocol
+// is being used (#VC handler will ASSERT if lower 12-bits are not zero).
+//
+InterruptState = GetInterruptState ();
+if (InterruptState) {
+  DisableInterrupts ();
+}
+
+Pending   = 0;
+SvsmCallData->CallPending = 
+
+CurrentMsr = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+Msr.Uint64  = 0;
+Msr.SnpVmplRequest.Function = GHCB_INFO_SNP_VMPL_REQUEST;
+Msr.SnpVmplRequest.Vmpl = 0;
+AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.Uint64);
+
+//
+// Guest memory is used for the guest-SVSM communication, so fence the
+// invocation of the VMGEXIT instruction to ensure VMSA accesses are
+// synchronized properly.
+//
+MemoryFence ();
+Ret = AsmVmgExitSvsm (SvsmCallData);
+MemoryFence ();
+
+Msr.Uint64 = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+
+AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr);
+
+if (InterruptState) {
+  EnableInterrupts ();
+}
+
+if (Pending != 0) {
+  SnpTerminate ();
+}
+
+if ((Msr.SnpVmplResponse.Function != GHCB_INFO_SNP_VMPL_RESPONSE) ||
+(Msr.SnpVmplResponse.ErrorCode != 0))
+{
+  SnpTerminate ();
+}
+  } while (Ret == SVSM_ERR_INCOMPLETE || Ret == SVSM_ERR_BUSY);
+
+  return Ret;
+}
+
 /**
   Report the presence of an Secure Virtual Services Module (SVSM).
 
@@ -109,6 +182,114 @@ CcSvsmSnpGetCaa (
   return CcSvsmIsSvsmPresent () ? SvsmInfo->SvsmCaa : 0;
 }
 
+/**
+  Issue an SVSM request to perform the PVALIDATE instruction.
+
+  Invokes the SVSM to process the PVALIDATE instruction on behalf of the
+  guest to validate or invalidate the memory range specified.
+
+  @param[in]   Info   Pointer to a page state change structure
+
+**/
+STATIC
+VOID
+SvsmPvalidate (
+  IN SNP_PAGE_STATE_CHANGE_INFO  *Info
+  )
+{
+  SVSM_CALL_DATA  SvsmCallData;
+  SVSM_CAA*Caa;
+  SVSM_PVALIDATE_REQUEST  *Request;
+  SVSM_FUNCTION   Function;
+  BOOLEAN Validate;
+  UINTN   Entry;
+  UINTN   EntryLimit;
+  UINTN   Index;
+  UINTN   EndIndex;
+  UINT64  Gfn;
+  UINT64  GfnEnd;
+  UINTN   Ret;
+
+  Caa = (SVSM_CAA *)CcSvsmSnpGetCaa ();
+  SetMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer), 0);
+
+  Function.Id.Protocol = 0;
+  Function.Id.CallId   = 1;
+
+  Request= (SVSM_PVALIDATE_REQUEST *)Caa->SvsmBuffer;
+  EntryLimit = ((sizeof (Caa->SvsmBuffer) - sizeof (*Request)) /
+sizeof (Request->Entry[0])) - 1;
+
+  SvsmCallData.Caa   = Caa;
+  SvsmCallData.RaxIn = Function.Uint64;
+  SvsmCallData.RcxIn = (UINT64)(UINTN)Request;
+
+  Entry= 0;
+  Index= Info->Header.CurrentEntry;
+  EndIndex = Info->Header.EndEntry;
+
+  while (Index <= EndIndex) {
+Validate = Info->Entry[Index].Operation == SNP_PAGE_STATE_PRIVATE;
+
+Request->Header.Entries++;
+Request->Entry[Entry].Bits.PageSize = Info->Entry[Index].PageSize;
+Request->Entry[Entry].Bits.Action   = (Validate == TRUE) ? 1 : 0;
+Request->Entry[Entry].Bits.IgnoreCf = 0;
+Request->Entry[Entry].Bits.Address  = Info->Entry[Index].GuestFrameNumber;
+
+Entry++;
+if ((Entry > EntryLimit) || (Index == EndIndex)) {
+  Ret = SvsmMsrProtocol ();
+  if ((Ret == SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH) &&
+  (Request->Entry[Request->Header.Next].Bits.PageSize != 0))
+  {
+// Calculate the Index of the entry after the entry that failed
+// before clearing 

[edk2-devel] [PATCH v2 17/23] OvmfPkg: Create a calling area used to communicate with the SVSM

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

An SVSM requires a calling area page whose address (CAA) is used by the
SVSM to communicate and process the SVSM request.

Add a pre-defined page area to the OvmfPkg and AmdSev packages and define
corresponding PCDs used to communicate the location and size of the area.
Keep the AmdSev package in sync with the OvmfPkg and adjust the AmdSev
launch and hash area memory locations.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/OvmfPkg.dec |  4 
 OvmfPkg/AmdSev/AmdSevX64.fdf|  9 ++---
 OvmfPkg/OvmfPkgX64.fdf  |  3 +++
 OvmfPkg/PlatformPei/PlatformPei.inf |  2 ++
 OvmfPkg/ResetVector/ResetVector.inf |  2 ++
 OvmfPkg/PlatformPei/AmdSev.c| 11 +++
 OvmfPkg/ResetVector/ResetVector.nasmb   |  6 --
 OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm | 11 ++-
 8 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index fbc81e4c8070..2f7bded9260b 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -338,6 +338,10 @@ [PcdsFixedAtBuild]
   ## Restrict boot to EFI applications in firmware volumes.
   gUefiOvmfPkgTokenSpaceGuid.PcdBootRestrictToFirmware|FALSE|BOOLEAN|0x6c
 
+  ## The base address and size of the initial SVSM Calling Area.
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase|0|UINT32|0x70
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize|0|UINT32|0x71
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 9dd409596780..dafa5ebacbaf 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -68,13 +68,16 @@ [FD.MEMFD]
 0x00E000|0x001000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
 
-0x00F000|0x000C00
+0x00F000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
+
+0x01|0x000C00
 
gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
 
-0x00FC00|0x000400
+0x010C00|0x000400
 
gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
 
-0x01|0x01
+0x011000|0x00F000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
 0x02|0x0E
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index f47ab1727e4c..f12844f674e7 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -94,6 +94,9 @@ [FD.MEMFD]
 0x00E000|0x001000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
 
+0x00F000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
+
 0x01|0x01
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index 7de3b4341c2c..126085db0204 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -128,6 +128,8 @@ [FixedPcd]
   gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
b/OvmfPkg/ResetVector/ResetVector.inf
index a4154ca90c28..0f5f8fec0b77 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -62,5 +62,7 @@ [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecSvsmCaaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 472cf13f0faa..66f480ee1c5d 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -554,5 +554,16 @@ SevInitializeRam (
   (UINT64)(UINTN)PcdGet32 (PcdOvmfCpuidSize),
   EfiReservedMemoryType
   );
+
+//
+// The calling area memory needs to be protected until the OS can create
+// its own calling area. Mark it as EfiReservedMemoryType so that the
+// guest firmware and OS do not use it as a system memory.
+//
+BuildMemoryAllocationHob (
+  

[edk2-devel] [PATCH v2 16/23] OvmfPkg/BaseMemEncryptSevLib: Use CcSvsmSnpPvalidate() to validate pages

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The PVALIDATE instruction is used to change the SNP validation of a page,
but that can only be done when running at VMPL0. To prepare for running at
a less priviledged VMPL, use the CcSvsmLib library API to perform the
PVALIDATE. The CcSvsmLib library will perform the proper operation on
behalf of the caller.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf  |  3 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf  |  3 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf  |  3 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 74 
+---
 4 files changed, 9 insertions(+), 74 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
index cc24961c9265..7397e5cfb810 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Library provides the helper functions for SEV guest
 #
-# Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -52,6 +52,7 @@ [LibraryClasses]
   MemoryAllocationLib
   PcdLib
   CcExitLib
+  CcSvsmLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 8f56783da55e..55928f9e386c 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Library provides the helper functions for SEV guest
 #
-# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -52,6 +52,7 @@ [LibraryClasses]
   MemoryAllocationLib
   PcdLib
   CcExitLib
+  CcSvsmLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
index b6d76e7e630f..e373f9f010ba 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
@@ -1,7 +1,7 @@
 ## @file
 #  Library provides the helper functions for SEV guest
 #
-# Copyright (c) 2020 Advanced Micro Devices. All rights reserved.
+# Copyright (c) 2020 - 2024, Advanced Micro Devices. All rights reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -49,6 +49,7 @@ [LibraryClasses]
   DebugLib
   PcdLib
   CcExitLib
+  CcSvsmLib
 
 [FixedPcd]
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase
diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index f1883239a661..4e1225d12797 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -14,14 +14,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
 #include "SnpPageStateChange.h"
 
-#define PAGES_PER_LARGE_ENTRY  512
-
 STATIC
 UINTN
 MemoryStateToGhcbOp (
@@ -63,73 +62,6 @@ SnpPageStateFailureTerminate (
   CpuDeadLoop ();
 }
 
-/**
- This function issues the PVALIDATE instruction to validate or invalidate the 
memory
- range specified. If PVALIDATE returns size mismatch then it retry validating 
with
- smaller page size.
-
- */
-STATIC
-VOID
-PvalidateRange (
-  IN  SNP_PAGE_STATE_CHANGE_INFO  *Info
-  )
-{
-  UINTN RmpPageSize;
-  UINTN StartIndex;
-  UINTN EndIndex;
-  UINTN Index;
-  UINTN Ret;
-  EFI_PHYSICAL_ADDRESS  Address;
-  BOOLEAN   Validate;
-
-  StartIndex = Info->Header.CurrentEntry;
-  EndIndex   = Info->Header.EndEntry;
-
-  for ( ; StartIndex <= EndIndex; StartIndex++) {
-//
-// Get the address and the page size from the Info.
-//
-Address = 
((EFI_PHYSICAL_ADDRESS)Info->Entry[StartIndex].GuestFrameNumber) << 
EFI_PAGE_SHIFT;
-RmpPageSize = Info->Entry[StartIndex].PageSize;
-Validate= Info->Entry[StartIndex].Operation == SNP_PAGE_STATE_PRIVATE;
-
-Ret = AsmPvalidate (RmpPageSize, Validate, Address);
-
-//
-// If we fail to validate due to size mismatch then try with the
-// smaller page size. This senario will occur if the backing page in
-// the RMP entry is 4K and we are validating it as a 2MB.
-//
-if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == 

[edk2-devel] [PATCH v2 15/23] UefiCpuPkg/MpInitLib: Use CcSvsmSnpVmsaRmpAdjust() to set/clear VMSA

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to change the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. To
prepare for running at a less priviledged VMPL, use the CcSvsmLib library
API to perform the RMPADJUST. The CcSvsmLib library will perform the
proper operation on behalf of the caller.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/MpLib.h  | 14 -
 UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c| 20 
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 54 +++-
 5 files changed, 9 insertions(+), 81 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 538a2146ff24..1b6abc4440cb 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -57,6 +57,7 @@ [LibraryClasses]
   SynchronizationLib
   PcdLib
   CcExitLib
+  CcSvsmLib
   MicrocodeLib
 [LibraryClasses.X64]
   CpuPageTableLib
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 622baec45e2f..9077114b1e6d 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -53,6 +53,7 @@ [LibraryClasses]
   PeiServicesLib
   PcdLib
   CcExitLib
+  CcSvsmLib
   MicrocodeLib
 
 [Pcd]
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 617f7401aea8..53a25c4634a1 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -870,20 +870,6 @@ FillExchangeInfoDataSevEs (
   IN volatile MP_CPU_EXCHANGE_INFO  *ExchangeInfo
   );
 
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  );
-
 /**
   Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index 0478e92317f1..963bd62494b9 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
@@ -49,26 +49,6 @@ SevSnpCreateAP (
   ASSERT (FALSE);
 }
 
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  )
-{
-  //
-  // RMPADJUST is not supported in 32-bit mode
-  //
-  return RETURN_UNSUPPORTED;
-}
-
 /**
   Determine if the SEV-SNP AP Create protocol should be used.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index 5d92c441adcd..bb4a52b25cd2 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -10,6 +10,7 @@
 
 #include "MpLib.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -38,20 +39,15 @@ SevSnpPerformApAction (
   BOOLEAN   InterruptState;
   UINT64ExitInfo1;
   UINT64ExitInfo2;
-  UINT32RmpAdjustStatus;
   UINT64VmgExitStatus;
+  EFI_STATUSVmsaStatus;
 
   if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
 //
-// To turn the page into a recognized VMSA page, issue RMPADJUST:
-//   Target VMPL but numerically higher than current VMPL
-//   Target PermissionMask is not used
+// Turn the page into a recognized VMSA page.
 //
-RmpAdjustStatus = SevSnpRmpAdjust (
-(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
-TRUE
-);
-if (RmpAdjustStatus != 0) {
+VmsaStatus = CcSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
+if (EFI_ERROR (VmsaStatus)) {
   DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA creation\n"));
   ASSERT (FALSE);
 
@@ -94,11 +90,8 @@ SevSnpPerformApAction (
 // Make the current VMSA not runnable and accessible to be
 // reprogrammed.
 //
-RmpAdjustStatus = SevSnpRmpAdjust (
-(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
-FALSE
-);
-if (RmpAdjustStatus != 0) {
+VmsaStatus = CcSvsmSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
+if (EFI_ERROR (VmsaStatus)) {
   DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA reset\n"));
   ASSERT (FALSE);
 
@@ -328,39 +321,6 @@ SevSnpCreateAP (
   }
 }
 
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage

[edk2-devel] [PATCH v2 14/23] Ovmfpkg/CcSvsmLib: Create CcSvsmLib to handle SVSM related services

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Add initial support for the new CcSvsmLib library to OvmfPkg. The initial
implementation will fully implement the SVSM presence check API and the
SVSM VMPL API, with later patches fully implementing the other interfaces.

The SVSM presence check, CcSvsmIsSvsmPresent(), determines the presence
of an SVSM by checking if an SVSM has been advertised in the SEV-SNP
Secrets Page. The SVSM VMPL API, CcSvsmSnpGetVmpl(), returns the VMPL
level at which OVMF is currently running.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/AmdSev/AmdSevX64.dsc|   1 +
 OvmfPkg/Bhyve/BhyveX64.dsc  |   1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc  |   1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc|   1 +
 OvmfPkg/Microvm/MicrovmX64.dsc  |   1 +
 OvmfPkg/OvmfPkgIa32.dsc |   1 +
 OvmfPkg/OvmfPkgIa32X64.dsc  |   3 +-
 OvmfPkg/OvmfPkgX64.dsc  |   1 +
 OvmfPkg/OvmfXen.dsc |   1 +
 OvmfPkg/Library/CcSvsmLib/CcSvsmLib.inf |  38 +++
 OvmfPkg/Library/CcSvsmLib/CcSvsmLib.c   | 267 
 11 files changed, 315 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index a31a89344a60..be0bfe3b017d 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -208,6 +208,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
+  CcSvsmLib|OvmfPkg/Library/CcSvsmLib/CcSvsmLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
   TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
 
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 9689a2f14efa..69e5c33126a3 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -234,6 +234,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  CcSvsmLib|UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
 
 [LibraryClasses.common.SEC]
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index b522fa10594d..31d8da0a1a61 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -244,6 +244,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
+  CcSvsmLib|OvmfPkg/Library/CcSvsmLib/CcSvsmLib.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
   TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
 
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 82e3e41cfc57..6fbe4bb17573 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -215,6 +215,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
+  CcSvsmLib|UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
   TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLib.inf
   PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 063324cd0572..7110c4805acf 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -242,6 +242,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf
+  CcSvsmLib|OvmfPkg/Library/CcSvsmLib/CcSvsmLib.inf
   
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
   
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
   FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 28379961a78e..dc9d7233da15 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -251,6 +251,7 @@ [LibraryClasses]
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  CcSvsmLib|UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
   TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
 
 [LibraryClasses.common.SEC]
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 5e9eee628aea..afdb33023e85 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -4,7 +4,7 @@
 #  Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
 #  (C) Copyright 2016 Hewlett Packard Enterprise Development LP
 #  Copyright (c) Microsoft Corporation.
-#  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 

[edk2-devel] [PATCH v2 13/23] UefiPayloadPkg: Prepare UefiPayloadPkg to use the CcSvsmLib library

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The MpInitLib library will be updated to use the new CcSvsmLib library.
To prevent any build breakage, update the UefiPayloadPkg DSC file to
include the CcSvsmLib NULL library.

Signed-off-by: Tom Lendacky 
---
 UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc 
b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 0e142bb7c2a2..2d468b43a786 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -331,6 +331,7 @@ [LibraryClasses]
   
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
   
VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  CcSvsmLib|UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
   
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
   FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
 [LibraryClasses.common]
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115848): https://edk2.groups.io/g/devel/message/115848
Mute This Topic: https://groups.io/mt/104512961/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 12/23] UefiCpuPkg/CcSvsmLib: Create the CcSvsmLib library to support an SVSM

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

In order to support an SEV-SNP guest running under an SVSM at VMPL1 or
lower, a new CcSvsmLib library must be created.

This library includes an interface to detect if running under an SVSM, an
interface to return the current VMPL, an interface to perform memory
validation and an interface to set or clear the attribute that allows a
page to be used as a VMSA.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/UefiCpuPkg.dec  |   5 +-
 UefiCpuPkg/UefiCpuPkg.dsc  |   4 +-
 UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf |  27 +
 UefiCpuPkg/Include/Library/CcSvsmLib.h | 101 ++
 UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.c   | 108 
 UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.uni |  13 +++
 6 files changed, 256 insertions(+), 2 deletions(-)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 571b59b36f0a..4a383c6d1d4d 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -2,7 +2,7 @@
 # This Package provides UEFI compatible CPU modules and libraries.
 #
 # Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -52,6 +52,9 @@ [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Provides function to support CcExit processing.
   CcExitLib|Include/Library/CcExitLib.h
 
+  ##  @libraryclass  Provides function to support CcSvsm processing.
+  CcSvsmLib|Include/Library/CcSvsmLib.h
+
   ##  @libraryclass  Provides function to get CPU cache information.
   CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h
 
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 10b33594e586..1ee726e6c6b5 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -2,7 +2,7 @@
 #  UefiCpuPkg Package
 #
 #  Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
-#  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+#  Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -61,6 +61,7 @@ [LibraryClasses]
   
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
   
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
   CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  CcSvsmLib|UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
   MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf
   
SmmCpuRendezvousLib|UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf
   CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf
@@ -159,6 +160,7 @@ [Components.IA32, Components.X64]
   UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf
   UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf
   UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+  UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
   UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
   UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
   UefiCpuPkg/SecCore/SecCore.inf
diff --git a/UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf 
b/UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
new file mode 100644
index ..b45a75941a8a
--- /dev/null
+++ b/UefiCpuPkg/Library/CcSvsmLibNull/CcSvsmLibNull.inf
@@ -0,0 +1,27 @@
+## @file
+#  CcSvsm Base Support Library.
+#
+#  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 1.29
+  BASE_NAME  = CcSvsmLibNull
+  MODULE_UNI_FILE= CcSvsmLibNull.uni
+  FILE_GUID  = 62b45e0f-c9b4-45ce-a5b3-41762709b3d9
+  MODULE_TYPE= BASE
+  VERSION_STRING = 1.0
+  LIBRARY_CLASS  = CcSvsmLib
+
+[Sources.common]
+  CcSvsmLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+
diff --git a/UefiCpuPkg/Include/Library/CcSvsmLib.h 
b/UefiCpuPkg/Include/Library/CcSvsmLib.h
new file mode 100644
index ..4715f4db3bd1
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/CcSvsmLib.h
@@ -0,0 +1,101 @@
+/** @file
+  Public header file for the CcSvsmLib.
+
+  This library class defines some routines used for invoking an SVSM when the
+  guest is not running at VMPL0.
+
+  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CC_SVSM_LIB_H_
+#define CC_SVSM_LIB_H_
+
+#include 
+#include 
+
+/**
+  Report the presence of an Secure Virtual Services Module (SVSM).
+
+  Determines the 

[edk2-devel] [PATCH v2 11/23] MdePkg/BaseLib: Add a new VMGEXIT instruction invocation for SVSM

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SVSM specification relies on a specific register calling convention to
hold the parameters that are associated with the SVSM request. The SVSM is
invoked by requesting the hypervisor to run the VMPL0 VMSA of the guest
using the GHCB MSR Protocol or a GHCB NAE event.

Create a new version of the VMGEXIT instruction that will adhere to this
calling convention and load the SVSM function arguments into the proper
register before invoking the VMGEXIT instruction. On return, perform the
atomic exchange on the SVSM call pending value as specified in the SVSM
specification.

Signed-off-by: Tom Lendacky 
---
 MdePkg/Library/BaseLib/BaseLib.inf   |  2 +
 MdePkg/Include/Library/BaseLib.h | 39 
 MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm | 39 
 MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm  | 94 
 4 files changed, 174 insertions(+)

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf 
b/MdePkg/Library/BaseLib/BaseLib.inf
index 4dbe94be71e1..26e66a8d67cf 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -187,6 +187,7 @@ [Sources.Ia32]
   Ia32/XGetBv.nasm
   Ia32/XSetBv.nasm
   Ia32/VmgExit.nasm
+  Ia32/VmgExitSvsm.nasm
 
   Ia32/DivS64x64Remainder.c
   Ia32/InternalSwitchStack.c | MSFT
@@ -328,6 +329,7 @@ [Sources.X64]
   X64/XGetBv.nasm
   X64/XSetBv.nasm
   X64/VmgExit.nasm
+  X64/VmgExitSvsm.nasm
   ChkStkGcc.c  | GCC
 
 [Sources.EBC]
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 1fff0fb224f1..95f805599d9d 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7876,6 +7876,45 @@ AsmVmgExit (
   VOID
   );
 
+///
+/// The structure used to supply and return data to and from the SVSM.
+///
+typedef struct {
+  VOID  *Caa;
+  UINT64RaxIn;
+  UINT64RcxIn;
+  UINT64RdxIn;
+  UINT64R8In;
+  UINT64R9In;
+  UINT64RaxOut;
+  UINT64RcxOut;
+  UINT64RdxOut;
+  UINT64R8Out;
+  UINT64R9Out;
+  UINT8 *CallPending;
+} SVSM_CALL_DATA;
+
+/**
+  Executes a VMGEXIT instruction (VMMCALL with a REP prefix) with arguments
+  and return code
+
+  Executes a VMGEXIT instruction placing the specified arguments in the
+  corresponding registers before invocation. Upon return an XCHG is done to
+  atomically clear and retrieve the SVSM call pending value. The returned RAX
+  register value becomes the function return code. This function is intended
+  for use with an SVSM. This function is only available on IA-32 and x64.
+
+  @param[in,out]  SvsmCallPending  Pointer to the location of the SVSM call 
data
+
+  @return  Value of the RAX register on return
+
+**/
+UINT32
+EFIAPI
+AsmVmgExitSvsm (
+  IN OUT SVSM_CALL_DATA  *SvsmCallData
+  );
+
 /**
   Patch the immediate operand of an IA32 or X64 instruction such that the byte,
   word, dword or qword operand is encoded at the end of the instruction's
diff --git a/MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm 
b/MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm
new file mode 100644
index ..14717bd1af02
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/VmgExitSvsm.nasm
@@ -0,0 +1,39 @@
+;--
+;
+; Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   VmgExitSvsm.Asm
+;
+; Abstract:
+;
+;   AsmVmgExitSvsm function
+;
+; Notes:
+;
+;--
+
+DEFAULT REL
+SECTION .text
+
+;--
+; UINT32
+; EFIAPI
+; AsmVmgExitSvsm (
+;   SVSM_CALL_DATA *SvsmCallData
+;   );
+;--
+global ASM_PFX(AsmVmgExitSvsm)
+ASM_PFX(AsmVmgExitSvsm):
+;
+; NASM doesn't support the vmmcall instruction in 32-bit mode and NASM versions
+; before 2.12 cannot translate the 64-bit "rep vmmcall" instruction into elf32
+; format. Given that VMGEXIT does not make sense on IA32, provide a stub
+; implementation that is identical to CpuBreakpoint(). In practice,
+; AsmVmgExitSvsm() should never be called on IA32.
+;
+int  3
+ret
+
diff --git a/MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm 
b/MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm
new file mode 100644
index ..b8af78890611
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/VmgExitSvsm.nasm
@@ -0,0 +1,94 @@
+;--
+;
+; Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   VmgExitSvsm.Asm
+;
+; Abstract:
+;
+;   AsmVmgExitSvsm function
+;
+; Notes:
+;

[edk2-devel] [PATCH v2 10/23] MdePkg/Register/Amd: Define the SVSM related information

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The Secure VM Service Module specification defines the interfaces needed
to allow multi-VMPL level execution of an SEV-SNP guest.

Define the SVSM related structures for the SVSM Calling Area as well as
the SVSM CAA MSR. The SVSM CAA MSR is an MSR register that is reserved for
software use and will not be implemented in hardware.

Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 MdePkg/Include/Register/Amd/Fam17Msr.h |  19 +++-
 MdePkg/Include/Register/Amd/Msr.h  |   3 +-
 MdePkg/Include/Register/Amd/Svsm.h | 101 
 MdePkg/Include/Register/Amd/SvsmMsr.h  |  35 +++
 4 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Fam17Msr.h 
b/MdePkg/Include/Register/Amd/Fam17Msr.h
index bb4e143e2456..f2d5ccb39dc7 100644
--- a/MdePkg/Include/Register/Amd/Fam17Msr.h
+++ b/MdePkg/Include/Register/Amd/Fam17Msr.h
@@ -6,7 +6,7 @@
   returned is a single 32-bit or 64-bit value, then a data structure is not
   provided for that MSR.
 
-  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.
+  Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Specification Reference:
@@ -71,9 +71,24 @@ typedef union {
 UINT32ErrorCode;
   } SnpPageStateChangeResponse;
 
+  struct {
+UINT64Function  : 12;
+UINT64Reserved1 : 20;
+UINT64Vmpl  : 8;
+UINT64Reserved2 : 56;
+  } SnpVmplRequest;
+
+  struct {
+UINT32Function : 12;
+UINT32Reserved : 20;
+UINT32ErrorCode;
+  } SnpVmplResponse;
+
   VOID  *Ghcb;
 
   UINT64GhcbPhysicalAddress;
+
+  UINT64Uint64;
 } MSR_SEV_ES_GHCB_REGISTER;
 
 #define GHCB_INFO_SEV_INFO1
@@ -84,6 +99,8 @@ typedef union {
 #define GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE  19
 #define GHCB_INFO_SNP_PAGE_STATE_CHANGE_REQUEST   20
 #define GHCB_INFO_SNP_PAGE_STATE_CHANGE_RESPONSE  21
+#define GHCB_INFO_SNP_VMPL_REQUEST22
+#define GHCB_INFO_SNP_VMPL_RESPONSE   23
 #define GHCB_HYPERVISOR_FEATURES_REQUEST  128
 #define GHCB_HYPERVISOR_FEATURES_RESPONSE 129
 #define GHCB_INFO_TERMINATE_REQUEST   256
diff --git a/MdePkg/Include/Register/Amd/Msr.h 
b/MdePkg/Include/Register/Amd/Msr.h
index 084eb892cdd9..04a3cbeb4315 100644
--- a/MdePkg/Include/Register/Amd/Msr.h
+++ b/MdePkg/Include/Register/Amd/Msr.h
@@ -6,7 +6,7 @@
   returned is a single 32-bit or 64-bit value, then a data structure is not
   provided for that MSR.
 
-  Copyright (c) 2017 - 2019, Advanced Micro Devices. All rights reserved.
+  Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Specification Reference:
@@ -19,5 +19,6 @@
 
 #include 
 #include 
+#include 
 
 #endif
diff --git a/MdePkg/Include/Register/Amd/Svsm.h 
b/MdePkg/Include/Register/Amd/Svsm.h
new file mode 100644
index ..9a989f803107
--- /dev/null
+++ b/MdePkg/Include/Register/Amd/Svsm.h
@@ -0,0 +1,101 @@
+/** @file
+  Secure VM Service Module (SVSM) Definition.
+
+  Provides data types allowing an SEV-SNP guest to interact with the SVSM.
+
+  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Specification Reference:
+  Secure VM Service Module Specification
+
+**/
+
+#ifndef SVSM_H_
+#define SVSM_H_
+
+#include 
+#include 
+#include 
+
+//
+// The SVSM definitions are part of the SNP Secrets Page:
+//   An SVSM is considered present if the SvsmSize field is non-zero.
+//
+typedef PACKED struct {
+  UINT8 Reserved1[320];
+
+  UINT64SvsmBase;
+  UINT64SvsmSize;
+  UINT64SvsmCaa;
+  UINT32SvsmMaxVersion;
+  UINT8 SvsmGuestVmpl;
+  UINT8 Reserved2[3];
+} SVSM_INFORMATION;
+
+typedef PACKED struct {
+  UINT8SvsmCallPending;
+  UINT8SvsmMemAvailable;
+  UINT8Reserved1[6];
+
+  //
+  // The remainder of the CAA 4KB area can be used for argument
+  // passing to the SVSM.
+  //
+  UINT8SvsmBuffer[SIZE_4KB - 8];
+} SVSM_CAA;
+
+#define SVSM_SUCCESS   0x
+#define SVSM_ERR_INCOMPLETE0x8000
+#define SVSM_ERR_UNSUPPORTED_PROTOCOL  0x8001
+#define SVSM_ERR_UNSUPPORTED_CALL  0x8002
+#define SVSM_ERR_INVALID_ADDRESS   0x8003
+#define SVSM_ERR_INVALID_FORMAT0x8004
+#define SVSM_ERR_INVALID_PARAMETER 0x8005
+#define SVSM_ERR_INVALID_REQUEST   0x8006
+#define SVSM_ERR_BUSY  0x8007
+
+#define SVSM_ERR_PVALIDATE_FAIL_INPUT  0x80001001
+#define SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH  0x80001006
+#define SVSM_ERR_PVALIDATE_FAIL_NO_CHANGE  0x80001010
+
+typedef PACKED struct {
+  UINT16Entries;
+  UINT16Next;
+
+  UINT8 Reserved[4];
+} SVSM_PVALIDATE_HEADER;
+
+typedef union {
+  struct {
+UINT64

[edk2-devel] [PATCH v2 09/23] OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When building the Page State Change entries for a range of memory, it can
happen that multiple calls to BuildPageStateBuffer() need to be made. If
the size of the input work area passed to BuildPageStateBuffer() exceeds
the number of entries that can be passed to the hypervisor using the GHCB
shared buffer, the Page State Change VMGEXIT support will issue multiple
VMGEXITs to process all entries in the buffer.

However, it could be that the final VMGEXIT for each round of Page State
Changes is only for a small number of entries and subsequent VMGEXITs may
still be issued to handle the full range of memory requested. To maximize
the number of entries processed during the Page State Change VMGEXIT,
limit BuildPageStateBuffer() to not build entries that exceed the maximum
number of entries that can be handled in a single Page State Change
VMGEXIT.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 11 
+++
 1 file changed, 11 insertions(+)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index bcc0798d6b02..f1883239a661 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -145,6 +145,7 @@ BuildPageStateBuffer (
   UINTN RmpPageSize;
   UINTN Index;
   UINTN IndexMax;
+  UINTN PscIndexMax;
 
   // Clear the page state structure
   SetMem (Info, InfoSize, 0);
@@ -153,6 +154,16 @@ BuildPageStateBuffer (
   IndexMax= (InfoSize - sizeof (Info->Header)) / sizeof (Info->Entry[0]);
   NextAddress = EndAddress;
 
+  //
+  // Make the use of the work area as efficient as possible relative to
+  // exiting from the guest to the hypervisor. Maximize the number of entries
+  // that can be processed per exit.
+  //
+  PscIndexMax = (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * 
SNP_PAGE_STATE_MAX_ENTRY;
+  if (PscIndexMax > 0) {
+IndexMax = MIN (IndexMax, PscIndexMax);
+  }
+
   //
   // Populate the page state entry structure
   //
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115844): https://edk2.groups.io/g/devel/message/115844
Mute This Topic: https://groups.io/mt/104512950/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 08/23] OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

In preparation for running under an SVSM at VMPL1 or higher (higher
numerically, lower privilege), re-organize the way a page state change
is performed in order to free up the GHCB for use by the SVSM support.

Currently, the page state change logic directly uses the GHCB shared
buffer to build the page state change structures. However, this will be
in conflict with the use of the GHCB should an SVSM call be required.

Instead, use a separate buffer (an area in the workarea during SEC and
an allocated page during PEI/DXE) to hold the page state change request
and only update the GHCB shared buffer as needed.

Since the information is copied to, and operated on, in the GHCB shared
buffer this has the added benefit of not requiring to save the start and
end entries for use when validating the memory during the page state
change sequence.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Include/WorkArea.h|   9 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h |   6 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c|  11 +-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c|  27 
-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c|  22 
+++-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c|  14 ++-
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 109 
+---
 7 files changed, 146 insertions(+), 52 deletions(-)

diff --git a/OvmfPkg/Include/WorkArea.h b/OvmfPkg/Include/WorkArea.h
index b1c7045ce18c..e3b415db2caa 100644
--- a/OvmfPkg/Include/WorkArea.h
+++ b/OvmfPkg/Include/WorkArea.h
@@ -2,7 +2,7 @@
 
   Work Area structure definition
 
-  Copyright (c) 2021, AMD Inc.
+  Copyright (c) 2021 - 2024, AMD Inc.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
@@ -54,6 +54,13 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
   // detection in OvmfPkg/ResetVector/Ia32/AmdSev.c
   //
   UINT8 ReceivedVc;
+  UINT8 Reserved[7];
+
+  // Used by SEC to generate Page State Change requests. This should be
+  // sized less than an equal to the GHCB shared buffer area to allow a
+  // single call to the hypervisor.
+  //
+  UINT8 WorkBuffer[1024];
 } SEC_SEV_ES_WORK_AREA;
 
 //
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
index 43319cc9ed17..5d23d1828b25 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChange.h
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -24,7 +24,9 @@ InternalSetPageState (
   IN EFI_PHYSICAL_ADDRESS  BaseAddress,
   IN UINTN NumPages,
   IN SEV_SNP_PAGE_STATEState,
-  IN BOOLEAN   UseLargeEntry
+  IN BOOLEAN   UseLargeEntry,
+  IN VOID  *PscBuffer,
+  IN UINTN PscBufferSize
   );
 
 VOID
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
index cbcdd46f528f..2515425e467a 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/DxeSnpSystemRamValidate.c
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -16,6 +16,8 @@
 #include "SnpPageStateChange.h"
 #include "VirtualMemory.h"
 
+STATIC VOID  *mPscBuffer = NULL;
+
 /**
   Pre-validate the system RAM when SEV-SNP is enabled in the guest VM.
 
@@ -52,5 +54,10 @@ MemEncryptSevSnpPreValidateSystemRam (
 }
   }
 
-  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE);
+  if (mPscBuffer == NULL) {
+mPscBuffer = AllocateReservedPages (1);
+ASSERT (mPscBuffer != NULL);
+  }
+
+  InternalSetPageState (BaseAddress, NumPages, SevSnpPagePrivate, TRUE, 
mPscBuffer, EFI_PAGE_SIZE);
 }
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index dee3fb8914ca..337a7d926b15 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -3,7 +3,7 @@
   Virtual Memory Management Services to set or clear the memory encryption bit
 
   Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
-  Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.
+  Copyright (c) 2017 - 2024, AMD Incorporated. All 

[edk2-devel] [PATCH v2 07/23] MdePkg: Avoid hardcoded value for number of Page State Change entries

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SNP_PAGE_STATE_MAX_ENTRY is based on the number of entries that can
fit in the GHCB shared buffer. As a result, the SNP_PAGE_STATE_CHANGE_INFO
structure maps the full GHCB shared buffer based on the shared buffer size
being 2032 bytes.

Instead of using a hardcoded value for SNP_PAGE_STATE_MAX_ENTRY, use a
build calculated value. Since the SNP_PAGE_STATE_CHANGE_INFO is used as a
mapping, eliminate the hardcoded array size so that the structure can be
used based on any size buffer.

Signed-off-by: Tom Lendacky 
---
 MdePkg/Include/Register/Amd/Ghcb.h | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h 
b/MdePkg/Include/Register/Amd/Ghcb.h
index 432d67e3e223..0cdc00627472 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -197,13 +197,14 @@ typedef struct {
   UINT32Reserved;
 } SNP_PAGE_STATE_HEADER;
 
-#define SNP_PAGE_STATE_MAX_ENTRY  253
-
 typedef struct {
   SNP_PAGE_STATE_HEADERHeader;
-  SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
+  SNP_PAGE_STATE_ENTRY Entry[];
 } SNP_PAGE_STATE_CHANGE_INFO;
 
+#define SNP_PAGE_STATE_MAX_ENTRY  \
+  ((sizeof (((GHCB *)0)->SharedBuffer) - sizeof (SNP_PAGE_STATE_HEADER)) / 
sizeof (SNP_PAGE_STATE_ENTRY))
+
 //
 // Get APIC IDs
 //
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115842): https://edk2.groups.io/g/devel/message/115842
Mute This Topic: https://groups.io/mt/104512946/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 06/23] OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State Change

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Calculate the amount of memory that can be use to build the Page State
Change data (SNP_PAGE_STATE_CHANGE_INFO) instead of using a hard-coded
size. This allows for changes to the GHCB shared buffer size without
having to make changes to the page state change code.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 12 

 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index 6a11adb06efb..60b176ab14b8 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -133,23 +133,26 @@ BuildPageStateBuffer (
   IN EFI_PHYSICAL_ADDRESSEndAddress,
   IN SEV_SNP_PAGE_STATE  State,
   IN BOOLEAN UseLargeEntry,
-  IN SNP_PAGE_STATE_CHANGE_INFO  *Info
+  IN SNP_PAGE_STATE_CHANGE_INFO  *Info,
+  IN UINTN   InfoSize
   )
 {
   EFI_PHYSICAL_ADDRESS  NextAddress;
   UINTN RmpPageSize;
   UINTN Index;
+  UINTN IndexMax;
 
   // Clear the page state structure
-  SetMem (Info, sizeof (*Info), 0);
+  SetMem (Info, InfoSize, 0);
 
   Index   = 0;
+  IndexMax= (InfoSize - sizeof (Info->Header)) / sizeof (Info->Entry[0]);
   NextAddress = EndAddress;
 
   //
   // Populate the page state entry structure
   //
-  while ((BaseAddress < EndAddress) && (Index < SNP_PAGE_STATE_MAX_ENTRY)) {
+  while ((BaseAddress < EndAddress) && (Index < IndexMax)) {
 //
 // Is this a 2MB aligned page? Check if we can use the Large RMP entry.
 //
@@ -265,7 +268,8 @@ InternalSetPageState (
 EndAddress,
 State,
 UseLargeEntry,
-Info
+Info,
+sizeof (Ghcb->SharedBuffer)
 );
 
 //
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115841): https://edk2.groups.io/g/devel/message/115841
Mute This Topic: https://groups.io/mt/104512944/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 05/23] OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

In prep for follow-on patches, fix an area of the code that does not meet
the uncrustify coding standards.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c | 27 
+++-
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index 46c6682760d5..6a11adb06efb 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -78,7 +78,9 @@ PvalidateRange (
   IN  BOOLEAN Validate
   )
 {
-  UINTN RmpPageSize, Ret, i;
+  UINTN RmpPageSize;
+  UINTN Index;
+  UINTN Ret;
   EFI_PHYSICAL_ADDRESS  Address;
 
   for ( ; StartIndex <= EndIndex; StartIndex++) {
@@ -96,7 +98,7 @@ PvalidateRange (
 // the RMP entry is 4K and we are validating it as a 2MB.
 //
 if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == 
PvalidatePageSize2MB)) {
-  for (i = 0; i < PAGES_PER_LARGE_ENTRY; i++) {
+  for (Index = 0; Index < PAGES_PER_LARGE_ENTRY; Index++) {
 Ret = AsmPvalidate (PvalidatePageSize4K, Validate, Address);
 if (Ret) {
   break;
@@ -135,18 +137,19 @@ BuildPageStateBuffer (
   )
 {
   EFI_PHYSICAL_ADDRESS  NextAddress;
-  UINTN i, RmpPageSize;
+  UINTN RmpPageSize;
+  UINTN Index;
 
   // Clear the page state structure
   SetMem (Info, sizeof (*Info), 0);
 
-  i   = 0;
+  Index   = 0;
   NextAddress = EndAddress;
 
   //
   // Populate the page state entry structure
   //
-  while ((BaseAddress < EndAddress) && (i < SNP_PAGE_STATE_MAX_ENTRY)) {
+  while ((BaseAddress < EndAddress) && (Index < SNP_PAGE_STATE_MAX_ENTRY)) {
 //
 // Is this a 2MB aligned page? Check if we can use the Large RMP entry.
 //
@@ -160,14 +163,14 @@ BuildPageStateBuffer (
   NextAddress = BaseAddress + EFI_PAGE_SIZE;
 }
 
-Info->Entry[i].GuestFrameNumber = BaseAddress >> EFI_PAGE_SHIFT;
-Info->Entry[i].PageSize = RmpPageSize;
-Info->Entry[i].Operation= MemoryStateToGhcbOp (State);
-Info->Entry[i].CurrentPage  = 0;
-Info->Header.EndEntry   = (UINT16)i;
+Info->Entry[Index].GuestFrameNumber = BaseAddress >> EFI_PAGE_SHIFT;
+Info->Entry[Index].PageSize = RmpPageSize;
+Info->Entry[Index].Operation= MemoryStateToGhcbOp (State);
+Info->Entry[Index].CurrentPage  = 0;
+Info->Header.EndEntry   = (UINT16)Index;
 
 BaseAddress = NextAddress;
-i++;
+Index++;
   }
 
   return NextAddress;
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115840): https://edk2.groups.io/g/devel/message/115840
Mute This Topic: https://groups.io/mt/104512941/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 04/23] UefiCpuPkg/MpInitLib: Always use AP Create if PcdSevSnpApicIds is set

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Currently, the first time an AP is started for an SEV-SNP guest, it relies
on the VMSA as set by the hypervisor. If the list of APIC IDs has been
retrieved, this is not necessary. Instead, use the SEV-SNP AP Create
protocol to start the AP for the first time and thereafter using the VMPL
at which the BSP is running.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/MpLib.h  | 15 +++-
 UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c| 21 +-
 UefiCpuPkg/Library/MpInitLib/MpLib.c  |  9 ++-
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 78 ++--
 6 files changed, 112 insertions(+), 13 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 55e46d4a1fad..538a2146ff24 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -68,6 +68,7 @@ [Guids]
   gEfiEventExitBootServicesGuid ## CONSUMES  ## Event
   gEfiEventLegacyBootGuid   ## SOMETIMES_CONSUMES  ## Event
   gEdkiiMicrocodePatchHobGuid   ## SOMETIMES_CONSUMES  ## HOB
+  gEfiApicIdsGuid   ## SOMETIMES_CONSUMES  ## HOB
 
 [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber## 
CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index bc3d716aa951..622baec45e2f 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -76,3 +76,4 @@ [Ppis]
 [Guids]
   gEdkiiS3SmmInitDoneGuid
   gEdkiiMicrocodePatchHobGuid
+  gEfiApicIdsGuid## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a96a6389c17d..617f7401aea8 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -2,7 +2,7 @@
   Common header file for MP Initialize Library.
 
   Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.
-  Copyright (c) 2020, AMD Inc. All rights reserved.
+  Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -911,6 +911,19 @@ SevSnpCreateAP (
   IN INTN ProcessorNumber
   );
 
+/**
+  Determine if the SEV-SNP AP Create protocol should be used.
+
+  @param[in]  CpuMpData  Pointer to CPU MP Data
+
+  @retval TRUE   Use SEV-SNP AP Create protocol
+  @retval FALSE  Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+CanUseSevSnpCreateAP (
+  IN  CPU_MP_DATA  *CpuMpData
+  );
+
 /**
   Get pointer to CPU MP Data structure from GUIDed HOB.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index c83144285b68..0478e92317f1 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
@@ -2,7 +2,7 @@
 
   AMD SEV helper function.
 
-  Copyright (c) 2021, AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -68,3 +68,22 @@ SevSnpRmpAdjust (
   //
   return RETURN_UNSUPPORTED;
 }
+
+/**
+  Determine if the SEV-SNP AP Create protocol should be used.
+
+  @param[in]  CpuMpData  Pointer to CPU MP Data
+
+  @retval TRUE   Use SEV-SNP AP Create protocol
+  @retval FALSE  Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+CanUseSevSnpCreateAP (
+  IN  CPU_MP_DATA  *CpuMpData
+  )
+{
+  //
+  // SEV-SNP is not supported on 32-bit build.
+  //
+  return FALSE;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c 
b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index cdfb570e61a0..dd8d00d54a15 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -2,7 +2,7 @@
   CPU MP Initialize Library common functions.
 
   Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.
-  Copyright (c) 2020, AMD Inc. All rights reserved.
+  Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -1302,9 +1302,10 @@ WakeUpAP (
   //
   // Wakeup all APs
   //   Must use the INIT-SIPI-SIPI method for initial configuration in
-  //   order to obtain the APIC ID.
+  //   order to obtain the APIC ID if not an SEV-SNP guest and the
+  //   list of APIC IDs is not available.
   //
-  if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != ApInitConfig)) 
{
+  if (CanUseSevSnpCreateAP (CpuMpData)) {
 SevSnpCreateAP (CpuMpData, -1);
   } else {
 if ((CpuMpData->InitFlag == ApInitConfig) && FixedPcdGetBool 
(PcdFirstTimeWakeUpAPsBySipi)) {
@@ -1414,7 +1415,7 @@ WakeUpAP (

[edk2-devel] [PATCH v2 03/23] OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

If the hypervisor supports retrieval of the vCPU APIC IDs, retrieve
them before any APs are actually started. The APIC IDs can be used
to start the APs for any SEV-SNP guest, but is a requirement for an
SEV-SNP guest that is running under an SVSM.

After retrieving the APIC IDs, save the address of the APIC ID data
structure in a GUIDed HOB.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/PlatformPei/PlatformPei.inf |  1 +
 OvmfPkg/PlatformPei/AmdSev.c| 91 +++-
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index ad52be306560..7de3b4341c2c 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -45,6 +45,7 @@ [Guids]
   gEfiMemoryTypeInformationGuid
   gFdtHobGuid
   gUefiOvmfPkgPlatformInfoGuid
+  gEfiApicIdsGuid
 
 [LibraryClasses]
   BaseLib
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index e6b602d79a05..472cf13f0faa 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -1,7 +1,7 @@
 /**@file
   Initialize Secure Encrypted Virtualization (SEV) support
 
-  Copyright (c) 2017 - 2020, Advanced Micro Devices. All rights reserved.
+  Copyright (c) 2017 - 2024, Advanced Micro Devices. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -31,6 +31,87 @@ GetHypervisorFeature (
   VOID
   );
 
+/**
+  Retrieve APIC IDs from the hypervisor.
+
+**/
+STATIC
+VOID
+AmdSevSnpGetApicIds (
+  VOID
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  GHCB  *Ghcb;
+  BOOLEAN   InterruptState;
+  UINT64VmgExitStatus;
+  UINT64PageCount;
+  BOOLEAN   PageCountValid;
+  VOID  *ApicIds;
+  RETURN_STATUS Status;
+  UINT64GuidData;
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+  Ghcb= Msr.Ghcb;
+
+  PageCount  = 0;
+  PageCountValid = FALSE;
+
+  CcExitVmgInit (Ghcb, );
+  Ghcb->SaveArea.Rax = PageCount;
+  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, 0, 0);
+  if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
+PageCount  = Ghcb->SaveArea.Rax;
+PageCountValid = TRUE;
+  }
+
+  CcExitVmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  ASSERT (PageCountValid);
+  if ((VmgExitStatus != 0) || !PageCountValid) {
+return;
+  }
+
+  //
+  // Allocate the memory for the APIC IDs
+  //
+  ApicIds = AllocateReservedPages ((UINTN)PageCount);
+  ASSERT (ApicIds != NULL);
+
+  Status = MemEncryptSevClearPageEncMask (
+ 0,
+ (UINTN)ApicIds,
+ (UINTN)PageCount
+ );
+  ASSERT_RETURN_ERROR (Status);
+
+  ZeroMem (ApicIds, EFI_PAGES_TO_SIZE ((UINTN)PageCount));
+
+  PageCountValid = FALSE;
+
+  CcExitVmgInit (Ghcb, );
+  Ghcb->SaveArea.Rax = PageCount;
+  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, (UINTN)ApicIds, 
0);
+  if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax) && (Ghcb->SaveArea.Rax == 
PageCount)) {
+PageCountValid = TRUE;
+  }
+
+  CcExitVmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  ASSERT (PageCountValid);
+  if ((VmgExitStatus != 0) || !PageCountValid) {
+FreePages (ApicIds, (UINTN)PageCount);
+return;
+  }
+
+  GuidData = (UINT64)(UINTN)ApicIds;
+  BuildGuidDataHob (, , sizeof (GuidData));
+}
+
 /**
   Initialize SEV-SNP support if running as an SEV-SNP guest.
 
@@ -78,6 +159,14 @@ AmdSevSnpInitialize (
   }
 }
   }
+
+  //
+  // Retrieve the APIC IDs if the hypervisor supports it. These will be used
+  // to always start APs using SNP AP Create.
+  //
+  if ((HvFeatures & GHCB_HV_FEATURES_APIC_ID_LIST) == 
GHCB_HV_FEATURES_APIC_ID_LIST) {
+AmdSevSnpGetApicIds ();
+  }
 }
 
 /**
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115838): https://edk2.groups.io/g/devel/message/115838
Mute This Topic: https://groups.io/mt/104512934/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 02/23] MdePkg: GHCB APIC ID retrieval support definitions

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When an SVSM is present, starting the APs requires knowledge of the APIC
IDs. Create the definitions required to retrieve and hold the APIC ID
information of all the vCPUs present in the guest.

Acked-by: Gerd Hoffmann 
Signed-off-by: Tom Lendacky 
---
 MdePkg/MdePkg.dec  |  5 -
 MdePkg/Include/Register/Amd/Ghcb.h | 16 +++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 0459418906f8..7d3f54a46f54 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -9,7 +9,7 @@
 # (C) Copyright 2016 - 2021 Hewlett Packard Enterprise Development LP
 # Copyright (c) 2022, Loongson Technology Corporation Limited. All rights 
reserved.
 # Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 # Copyright (c) 2023, Ampere Computing LLC. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -876,6 +876,9 @@ [Guids]
   ## Include/Protocol/CcMeasurement.h
   gEfiCcFinalEventsTableGuid = { 0xdd4a4648, 0x2de7, 0x4665, { 0x96, 0x4d, 
0x21, 0xd9, 0xef, 0x5f, 0xb4, 0x46 }}
 
+  ## Include/Register/Amd/Ghcb.h
+  gEfiApicIdsGuid= { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 
0x10, 0x10, 0x8b, 0x17, 0x80, 0x1b }}
+
 [Guids.IA32, Guids.X64]
   ## Include/Guid/Cper.h
   gEfiIa32X64ErrorTypeCacheCheckGuid = { 0xA55701F5, 0xE3EF, 0x43de, { 0xAC, 
0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C }}
diff --git a/MdePkg/Include/Register/Amd/Ghcb.h 
b/MdePkg/Include/Register/Amd/Ghcb.h
index dab396f3ede8..432d67e3e223 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -4,7 +4,7 @@
   Provides data types allowing an SEV-ES guest to interact with the hypervisor
   using the GHCB protocol.
 
-  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Specification Reference:
@@ -56,6 +56,7 @@
 #define SVM_EXIT_AP_JUMP_TABLE  0x8005ULL
 #define SVM_EXIT_SNP_PAGE_STATE_CHANGE  0x8010ULL
 #define SVM_EXIT_SNP_AP_CREATION0x8013ULL
+#define SVM_EXIT_GET_APIC_IDS   0x8017ULL
 #define SVM_EXIT_HYPERVISOR_FEATURES0x8000FFFDULL
 #define SVM_EXIT_UNSUPPORTED0x8000ULL
 
@@ -170,6 +171,7 @@ typedef union {
 #define GHCB_HV_FEATURES_SNP_AP_CREATE   (GHCB_HV_FEATURES_SNP 
| BIT1)
 #define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION
(GHCB_HV_FEATURES_SNP_AP_CREATE | BIT2)
 #define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION_TIMER  
(GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION | BIT3)
+#define GHCB_HV_FEATURES_APIC_ID_LISTBIT4
 
 //
 // SNP Page State Change.
@@ -202,6 +204,18 @@ typedef struct {
   SNP_PAGE_STATE_ENTRY Entry[SNP_PAGE_STATE_MAX_ENTRY];
 } SNP_PAGE_STATE_CHANGE_INFO;
 
+//
+// Get APIC IDs
+//
+#define EFI_APIC_IDS_GUID  \
+  { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 0x10, 0x10, 0x8b, 0x17, 0x80, 
0x1b }}
+extern EFI_GUID  gEfiApicIdsGuid;
+
+typedef struct {
+  UINT32NumEntries;
+  UINT32ApicIds[];
+} GHCB_APIC_IDS;
+
 //
 // SEV-ES save area mapping structures used for SEV-SNP AP Creation.
 // Only the fields required to be set to a non-zero value are defined.
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115837): https://edk2.groups.io/g/devel/message/115837
Mute This Topic: https://groups.io/mt/104512930/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 01/23] OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()

2024-02-22 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The AsmRmpAdjust() function returns a UINT32, however in SevSnpIsVmpl0()
the return value is checked with EFI_ERROR() when it should just be
compared to 0. Fix the error check.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
index 7797febb8ac6..be43a44e4e1d 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
@@ -2,7 +2,7 @@
 
   SEV-SNP Page Validation functions.
 
-  Copyright (c) 2021 AMD Incorporated. All rights reserved.
+  Copyright (c) 2021 - 2024, AMD Incorporated. All rights reserved.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -31,8 +31,8 @@ SevSnpIsVmpl0 (
   VOID
   )
 {
-  UINT64  Rdx;
-  EFI_STATUS  Status;
+  UINT64  Rdx;
+  UINT32  Status;
 
   //
   // There is no straightforward way to query the current VMPL level.
@@ -44,7 +44,7 @@ SevSnpIsVmpl0 (
   Rdx = 1;
 
   Status = AsmRmpAdjust ((UINT64)gVmpl0Data, 0, Rdx);
-  if (EFI_ERROR (Status)) {
+  if (Status != 0) {
 return FALSE;
   }
 
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115836): https://edk2.groups.io/g/devel/message/115836
Mute This Topic: https://groups.io/mt/104512928/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH v2 00/23] Provide SEV-SNP support for running under an SVSM

2024-02-22 Thread Lendacky, Thomas via groups.io


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

When running under an SVSM, OVMF must know the APIC IDs of the vCPUs that
it will be starting. As a result, the GHCB APIC ID retrieval action must
be performed. Since this service can also work with SEV-SNP running at
VMPL0, the patches to make use of this feature are near the beginning of
the series.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This support creates a new CcSvsmLib library that is used by MpInitLib.
This requires an update to the edk2-platform DSC files to add the new
library. The edk2-platform change would be needed after patch 12, but
before patch 15.

This series introduces support to run OVMF under an SVSM. It consists
of:
  - Retrieving the list of vCPU APIC IDs and starting up all APs without
performing a broadcast SIPI
  - Reorganizing the page state change support to not directly use the
GHCB buffer since an SVSM will use the calling area buffer, instead
  - Detecting the presence of an SVSM
  - When not running at VMPL0, invoking the SVSM for page validation and
VMSA page creation/deletion
  - Detecting and allowing OVMF to run in a VMPL other than 0 when an
SVSM is present

The series is based off of commit:

  2ca8d5597443 ("UefiCpuPkg/PiSmmCpuDxeSmm: Check BspIndex first before lock 
cmpxchg")

[1] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf
[2] 
https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf

---

Changes in v2:
- Move the APIC IDs retrieval support to the beginning of the patch series
- Use a GUIDed HOB to hold the APIC ID list instead of a PCD
- Split up Page State Change reorganization into multiple patches
- Created CcSvsmLib library instead of extending CcExitLib
- This will require a corresponding update to edk2-platform DSC files
- Removed Ray Ni's Acked-by since it is not a minor change
- Variable name changes and other misc changes

Tom Lendacky (23):
  OvmfPkg/BaseMemEncryptLib: Fix error check from AsmRmpAdjust()
  MdePkg: GHCB APIC ID retrieval support definitions
  OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
  UefiCpuPkg/MpInitLib: Always use AP Create if PcdSevSnpApicIds is set
  OvmfPkg/BaseMemEncryptSevLib: Fix uncrustify errors
  OvmfPkg/BaseMemEncryptSevLib: Calculate memory size for Page State
Change
  MdePkg: Avoid hardcoded value for number of Page State Change entries
  OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support
  OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency
  MdePkg/Register/Amd: Define the SVSM related information
  MdePkg/BaseLib: Add a new VMGEXIT instruction invocation for SVSM
  UefiCpuPkg/CcSvsmLib: Create the CcSvsmLib library to support an SVSM
  UefiPayloadPkg: Prepare UefiPayloadPkg to use the CcSvsmLib library
  Ovmfpkg/CcSvsmLib: Create CcSvsmLib to handle SVSM related services
  UefiCpuPkg/MpInitLib: Use CcSvsmSnpVmsaRmpAdjust() to set/clear VMSA
  OvmfPkg/BaseMemEncryptSevLib: Use CcSvsmSnpPvalidate() to validate
pages
  OvmfPkg: Create a calling area used to communicate with the SVSM
  OvmfPkg/CcSvsmLib: Add support for the SVSM_CORE_PVALIDATE call
  OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency
  OvmfPkg/CcSvsmLib: Add support for the SVSM create/delete vCPU calls
  UefiCpuPkg/MpInitLib: AP creation support under an SVSM
  Ovmfpkg/CcExitLib: Provide SVSM discovery support
  OvmfPkg/BaseMemEncryptLib: Check for presence of an SVSM when not at
VMPL0

 MdePkg/MdePkg.dec |   5 +-
 OvmfPkg/OvmfPkg.dec   |   4 +
 UefiCpuPkg/UefiCpuPkg.dec |   5 +-
 OvmfPkg/AmdSev/AmdSevX64.dsc  |   1 +
 OvmfPkg/Bhyve/BhyveX64.dsc|   1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc|   1 +
 OvmfPkg/IntelTdx/IntelTdxX64.dsc  |   1 +
 

Re: [edk2-devel] GuestPhysAddrSize questions

2024-02-22 Thread Lendacky, Thomas via groups.io

On 2/22/24 05:24, Gerd Hoffmann wrote:

   Hi,


+if (Cr4.Bits.LA57) {
+  if (PhysBits > 48) {
+/*
+ * Some Intel CPUs support 5-level paging, have more than 48
+ * phys-bits but support only 4-level EPT, which effectively
+ * limits guest phys-bits to 48.
+ *
+ * AMD Processors have a different but somewhat related
+ * problem: They can handle guest phys-bits larger than 48
+ * only in case the host runs in 5-level paging mode.
+ *
+ * Until we have some way to communicate that kind of
+ * limitations from hypervisor to guest, limit phys-bits
+ * to 48 unconditionally.
+ */


So I'm looking for some communication path.  One option would be to use
some bits in the KVM cpuid leaves.  Another possible candidate is cpuid
leaf 0x8008.

 From the AMD APM (revision 3.35):

   CPUID Fn8000_0008_EAX Long Mode Size Identifiers
   

   The value returned in EAX provides information about the maximum host
   and guest physical and linear address width (in bits) supported by the
   processor.

   Bits   FieldNameDescription

   31:24  —Reserved

   23:16 GuestPhysAddrSize Maximum guest physical address size in bits.
   This number applies only to guests using nested
   paging. When this field is zero, refer to the
   PhysAddrSize field for the maximum guest
   physical address size. See “Secure Virtual
   Machine” in APM Volume 2.

   15:8  LinAddrSize   Maximum linear address size in bits.

   7:0   PhysAddrSize  Maximum physical address size in bits. When
   GuestPhysAddrSize is zero, this field also
   indicates the maximum guest physical address
   size.

The description of the GuestPhysAddrSize is somewhat vague.  Is this a
value the hypervisor should use to figure how much address space it can
give to guests?  Or is this a value the hypervisor can set to inform the
guest about the available address space (which would be a solution to
the problem outlined in the comment above)?  Or both?


I believe the main purpose of GuestPhysAddrSize was for software use (for 
nested virtualization) and that the hardware itself has always returned 
zero for that value. So you should be able to use that field. Adding 
@Paolo for his thoughts.


Thanks,
Tom



In case GuestPhysAddrSize should not be used this way:  Is it possible
allocate the currently reserved bits 31:24 for that purpose?

Tom?  Michael?

thanks & take care,
   Gerd




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115824): https://edk2.groups.io/g/devel/message/115824
Mute This Topic: https://groups.io/mt/104510523/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH v3 5/6] OvmfPkg/ResetVector: add 5-level paging support

2024-02-20 Thread Lendacky, Thomas via groups.io

On 2/20/24 03:06, Gerd Hoffmann wrote:

Compile the OVMF ResetVector with 5-level paging support in case
PcdUse5LevelPageTable is TRUE.

When enabled the ResetVector will check at runtime whenever support for
5-level paging and gigabyte pages is available.  In case both features
are supported it will run OVMF in 5-level paging mode, otherwise
fallback to 4-level paging.

Gigabyte pages are required to make sure we can fit the page tables into
the available space.  We have six pages available, four of them are
used.  The first gibabyte is mapped with 2M pages, the 1GB -> 4GB range
uses gigabyte pages.  See the source code comment for the exact layout.

In case TDX is used the TDX_WORK_AREA_PGTBL_READY will carry the
information whenever 5-level paging is used (2) or not (1), so the
APs can pick the correct paging mode.

Signed-off-by: Gerd Hoffmann 
---
  OvmfPkg/ResetVector/ResetVector.inf   |   1 +
  OvmfPkg/ResetVector/Ia32/IntelTdx.asm |  17 ++-
  OvmfPkg/ResetVector/Ia32/PageTables64.asm | 131 +-
  OvmfPkg/ResetVector/ResetVector.nasmb |   1 +
  4 files changed, 145 insertions(+), 5 deletions(-)

diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
b/OvmfPkg/ResetVector/ResetVector.inf
index a4154ca90c28..65f71b05a02e 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -64,3 +64,4 @@ [FixedPcd]
gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable
diff --git a/OvmfPkg/ResetVector/Ia32/IntelTdx.asm 
b/OvmfPkg/ResetVector/Ia32/IntelTdx.asm
index 06794baef81d..3e50ca76aacf 100644
--- a/OvmfPkg/ResetVector/Ia32/IntelTdx.asm
+++ b/OvmfPkg/ResetVector/Ia32/IntelTdx.asm
@@ -179,7 +179,7 @@ InitTdx:
  ;
  ; Modified:  EAX, EDX
  ;
-; 0-NonTdx, 1-TdxBsp, 2-TdxAps
+; 0-NonTdx, 1-TdxBsp, 2-TdxAps, 3-TdxApsLa57
  ;
  CheckTdxFeaturesBeforeBuildPagetables:
  xor eax, eax
@@ -204,6 +204,21 @@ TdxPostBuildPageTables:
  ExitTdxPostBuildPageTables:
  OneTimeCallRet TdxPostBuildPageTables
  
+%if PG_5_LEVEL

+
+;
+; Set byte[TDX_WORK_AREA_PGTBL_READY] to 2
+;
+TdxPostBuildPageTablesLa57:
+cmp byte[WORK_AREA_GUEST_TYPE], VM_GUEST_TDX
+jne ExitTdxPostBuildPageTablesLa57
+mov byte[TDX_WORK_AREA_PGTBL_READY], 2
+
+ExitTdxPostBuildPageTablesLa57:
+OneTimeCallRet TdxPostBuildPageTablesLa57
+
+%endif
+
  ;
  ; Check if TDX is enabled
  ;
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm 
b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 6fec6f2beeea..21de75a40097 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -42,8 +42,10 @@ BITS32
   PAGE_READ_WRITE + \
   PAGE_PRESENT)
  
+%define NOT_TDX 0

  %define TDX_BSP 1
  %define TDX_AP  2
+%define TDX_AP_LA57 3
  
  ;

  ; Modified:  EAX, EBX, ECX, EDX
@@ -55,11 +57,21 @@ SetCr3ForPageTables64:
  ; the page tables. APs will spin on until byte[TDX_WORK_AREA_PGTBL_READY]
  ; is set.
  OneTimeCall   CheckTdxFeaturesBeforeBuildPagetables
+cmp   eax, NOT_TDX
+jeCheckSev
  cmp   eax, TDX_BSP
  jeClearOvmfPageTables
+%if PG_5_LEVEL
  cmp   eax, TDX_AP
  jeSetCr3
+; TDX_AP_LA57 -> set cr4.la57
+mov   eax, cr4
+bts   eax, 12
+mov   cr4, eax
+%endif
+jmp   SetCr3
  
+CheckSev:

  ; Check whether the SEV is active and populate the SevEsWorkArea
  OneTimeCall   CheckSevFeatures
  
@@ -86,6 +98,105 @@ clearPageTablesMemoryLoop:

  mov dword[ecx * 4 + PT_ADDR (0) - 4], eax
  loopclearPageTablesMemoryLoop
  
+%if PG_5_LEVEL

+
+; save GetSevCBitMaskAbove31 result (cpuid changes edx)
+mov edi, edx
+
+; check for cpuid leaf 0x07
+mov eax, 0x00
+cpuid
+cmp eax, 0x07
+jb  Paging4Lvl
+
+; check for la57 (aka 5-level paging)
+mov eax, 0x07
+mov ecx, 0x00
+cpuid
+bt  ecx, 16
+jnc Paging4Lvl
+
+; check for cpuid leaf 0x8001
+mov eax, 0x8000
+cpuid
+cmp eax, 0x8001
+jb  Paging4Lvl
+
+; check for 1g pages
+mov eax, 0x8001
+cpuid
+bt  edx, 26
+jnc Paging4Lvl
+
+;
+; Use 5-level paging with gigabyte pages.
+;
+; We have 6 pages available for the early page tables,
+; we use four of them:
+;PT_ADDR(0)  - level 5 directory
+;PT_ADDR(0x1000) - level 4 directory
+;PT_ADDR(0x2000) - level 2 directory (0 -> 1GB)
+;PT_ADDR(0x3000) - level 3 directory
+;
+; The level 2 directory for the first gigabyte has the same
+; physical address in both 4-level and 5-level paging mode,
+; SevClearPageEncMaskForGhcbPage depends on this.
+;

Re: [edk2-devel] [PATCH v3 4/6] OvmfPkg/ResetVector: SEV: keep #vc handler installed longer

2024-02-20 Thread Lendacky, Thomas via groups.io

On 2/20/24 03:06, Gerd Hoffmann wrote:

When running in SEV mode do not uninstall the #vc handler in
CheckSevFeatures.   Keep it active and uninstall it later in
SevClearPageEncMaskForGhcbPage.

This allows using the cpuid instruction in SetCr3ForPageTables64,
which is needed to check for la57 & 1G page support.

Signed-off-by: Gerd Hoffmann 


I think a comment should be added above where the #VC handler is 
established to document that the #VC handler is removed at the end of this 
function if SEV is not active or that it remains installed to support 
CPUID calls, e.g. to check for 5-level paging support, and is removed 
later in SevClearPageEncMaskForGhcbPage().


With that,

Reviewed-by: Tom Lendacky 


---
  OvmfPkg/ResetVector/Ia32/AmdSev.asm | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm 
b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
index 043c88a7abbe..02f287f1d934 100644
--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -158,6 +158,11 @@ SevClearPageEncMaskForGhcbPage:
  cmp   byte[WORK_AREA_GUEST_TYPE], 1
  jnz   SevClearPageEncMaskForGhcbPageExit
  
+; Clear exception handlers and stack

+mov   eax, ADDR_OF(IdtrClear)
+lidt  [cs:eax]
+mov   esp, 0
+
  ; Check if SEV-ES is enabled
  mov   ecx, 1
  bt[SEV_ES_WORK_AREA_STATUS_MSR], ecx
@@ -332,7 +337,6 @@ NoSevEsVcHlt:
  NoSevPass:
  xor   eax, eax
  
-SevExit:

  ;
  ; Clear exception handlers and stack
  ;
@@ -342,6 +346,7 @@ SevExit:
  pop   eax
  mov   esp, 0
  
+SevExit:

  OneTimeCallRet CheckSevFeatures
  
  ; Start of #VC exception handling routines



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115678): https://edk2.groups.io/g/devel/message/115678
Mute This Topic: https://groups.io/mt/104464311/21656
Mute #vc:https://edk2.groups.io/g/devel/mutehashtag/vc
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 00/16] Provide SEV-SNP support for running under an SVSM

2024-01-27 Thread Lendacky, Thomas via groups.io

On 1/26/24 22:04, Yao, Jiewen wrote:

Thanks Tom.
Please give me some time to digest this patch set before I can give some 
feedback.

One quick question to you:
With this patch, we need to support multiple SEV modes:
1. SEV guest firmware
2. SEV-ES guest firmware
3. SEV-SNP guest firmware
4. SEV-SNP SVSM guest firmware


This last mode is still an SNP guest, it just requires invoking an API to 
perform operations that require VMPL0 permissions. I'm not sure what you 
mean by having firmware at the end of each mode. The same firmware is used 
for all SEV guest modes as well as non-SEV guests.



And all these mode requires runtime detection. Am I right?


Yes


If so, where is the flag to set those mode?


There are function calls available to detect the SEV mode. See the 
implementation of MemEncryptSevIsEnabled(), MemEncryptSevEsIsEnabled() and 
MemEncryptSevSnpIsEnabled().


OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c

(OvmfPkg/Sec/AmdSev.c also has some early detection support)

Note:
  - An SEV-SNP guest is also considered an SEV-ES and SEV guest.
  - An SEV-ES guest is also considered an SEV guest.

Within the CcExitLib library, the decision to use the SVSM API will be 
based on the VMPL level at which OVMF is running.


Thanks,
Tom



Please correct me if my understanding is wrong.

Thank you
Yao, Jiewen


-Original Message-
From: Tom Lendacky 
Sent: Saturday, January 27, 2024 6:13 AM
To: devel@edk2.groups.io
Cc: Ard Biesheuvel ; Aktas, Erdem
; Gerd Hoffmann ; Yao, Jiewen
; Laszlo Ersek ; Liming Gao
; Kinney, Michael D ;
Xu, Min M ; Liu, Zhiguang ;
Kumar, Rahul R ; Ni, Ray ; Michael
Roth 
Subject: [PATCH 00/16] Provide SEV-SNP support for running under an SVSM


BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

This series adds SEV-SNP support for running OVMF under an Secure VM
Service Module (SVSM) at a less privileged VM Privilege Level (VMPL).
By running at a less priviledged VMPL, the SVSM can be used to provide
services, e.g. a virtual TPM, for the guest OS within the SEV-SNP
confidential VM (CVM) rather than trust such services from the hypervisor.

Currently, OVMF expects to run at the highest VMPL, VMPL0, and there are
certain SNP related operations that require that VMPL level. Specifically,
the PVALIDATE instruction and the RMPADJUST instruction when setting the
the VMSA attribute of a page (used when starting APs).

If OVMF is to run at a less privileged VMPL, e.g. VMPL2, then it must
use an SVSM (which is running at VMPL0) to perform the operations that
it is no longer able to perform.

How OVMF interacts with and uses the SVSM is documented in the SVSM
specification [1] and the GHCB specification [2].

This series introduces support to run OVMF under an SVSM. It consists
of:
   - Reorganize the page state change support to not directly use the
 GHCB buffer since an SVSM will use the calling area buffer, instead
   - Detecting the presence of an SVSM
   - When not running at VMPL0, invoking the SVSM for page validation and
 VMSA page creation/deletion
   - Retrieving the list of vCPU APIC IDs and starting up all APs without
 performing a broadcast SIPI
   - Detecting and allowing OVMF to run in a VMPL other than 0 when an
 SVSM is present

The series is based off of commit:

   7d7decfa3dc8 ("UefiPayloadPkg/Crypto: Support external Crypto drivers.")

[1] https://www.amd.com/content/dam/amd/en/documents/epyc-technical-
docs/specifications/58019.pdf
[2] https://www.amd.com/content/dam/amd/en/documents/epyc-technical-
docs/specifications/56421.pdf

---

Tom Lendacky (16):
   OvmfPkg/BaseMemEncryptSevLib: Re-organize page state change support
   MdePkg/Register/Amd: Define the SVSM related information
   MdePkg/BaseLib: Add a new VMGEXIT instruction invocation for SVSM
   UefiCpuPkg/CcExitLib: Extend the CcExitLib library to support an SVSM
   Ovmfpkg/CcExitLib: Extend CcExitLib to handle SVSM related services
   OvmfPkg: Create a calling area used to communicate with the SVSM
   OvmfPkg/CcExitLib: Add support for the SVSM_CORE_PVALIDATE call
   OvmfPkg/CcExitLib: Add support for the SVSM create/delete vCPU calls
   UefiCpuPkg/MpInitLib: Use CcExitSnpVmsaRmpAdjust() to set/clear VMSA
   MdePkg: GHCB APIC ID retrieval support definitions
   UefiCpuPkg: Create APIC ID list PCD
   OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor
   UefiCpuPkg/MpInitLib: Always use AP Create if PcdSevSnpApicIds is set
   UefiCpuPkg/MpInitLib: AP creation support under an SVSM
   Ovmfpkg/CcExitLib: Provide SVSM discovery support
   OvmfPkg/BaseMemEncryptLib: Check for presence of an SVSM when not at
 VMPL0

  OvmfPkg/OvmfPkg.dec   |   4 +
  UefiCpuPkg/UefiCpuPkg.dec |   7 +-
  OvmfPkg/AmdSev/AmdSevX64.fdf  

[edk2-devel] [PATCH 16/16] OvmfPkg/BaseMemEncryptLib: Check for presence of an SVSM when not at VMPL0

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Currently, an SEV-SNP guest will terminate if it is not running at VMPL0.
The requirement for running at VMPL0 is removed if an SVSM is present.

Update the current VMPL0 check to additionally check for the presence of
an SVSM is the guest is not running at VMPL0.

Additionally, fix an error in SevSnpIsVmpl0() where the Status variable
should be compared to 0 and not use the EFI_ERROR() function to determine
if an error occurred during AsmRmpAdjust().

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c | 11 
+++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
index 86af2ba0356e..803c835680e0 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SecSnpSystemRamValidate.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "SnpPageStateChange.h"
 
@@ -45,7 +46,7 @@ SevSnpIsVmpl0 (
   Rdx = 1;
 
   Status = AsmRmpAdjust ((UINT64)gVmpl0Data, 0, Rdx);
-  if (EFI_ERROR (Status)) {
+  if (Status != 0) {
 return FALSE;
   }
 
@@ -74,10 +75,12 @@ MemEncryptSevSnpPreValidateSystemRam (
 
   //
   // The page state change uses the PVALIDATE instruction. The instruction
-  // can be run on VMPL-0 only. If its not VMPL-0 guest then terminate
-  // the boot.
+  // can be run at VMPL-0 only. If its not a VMPL-0 guest, then an SVSM must
+  // be present to perform the operation on behalf of the guest. If the guest
+  // is not running at VMPL-0 and an SVSM is not present, then terminate the
+  // boot.
   //
-  if (!SevSnpIsVmpl0 ()) {
+  if (!SevSnpIsVmpl0 () && !CcExitSnpSvsmPresent ()) {
 SnpPageStateFailureTerminate ();
   }
 
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114642): https://edk2.groups.io/g/devel/message/114642
Mute This Topic: https://groups.io/mt/103986479/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 15/16] Ovmfpkg/CcExitLib: Provide SVSM discovery support

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The SVSM specification documents an alternative method of discovery for
the SVSM using a reserved CPUID bit and a reserved MSR.

For the CPUID support, the #VC handler of an SEV-SNP guest should modify
the returned value in the EAX register for the 0x801f CPUID function
by setting bit 28 when an SVSM is present.

For the MSR support, new reserved MSR 0xc001f000 has been defined. A #VC
should be generated when accessing this MSR. The #VC handler is expected
to ignore writes to this MSR and return the physical calling area address
(CAA) on reads of this MSR.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/CcExitLib/CcExitSvsm.h  | 29 
 OvmfPkg/Library/CcExitLib/CcExitSvsm.c  | 21 ++
 OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 29 ++--
 3 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Library/CcExitLib/CcExitSvsm.h 
b/OvmfPkg/Library/CcExitLib/CcExitSvsm.h
new file mode 100644
index ..2325e7a98910
--- /dev/null
+++ b/OvmfPkg/Library/CcExitLib/CcExitSvsm.h
@@ -0,0 +1,29 @@
+/** @file
+  Secure VM Service Module (SVSM) functions.
+
+  Copyright (C) 2024, Advanced Micro Devices, Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Specification Reference:
+  Secure VM Service Module Specification
+
+**/
+
+#ifndef __CCEXITLIB_CCEXITSVSM_H__
+#define __CCEXITLIB_CCEXITSVSM_H__
+
+/**
+  Return the physical address of SVSM Call Area (CAA).
+
+  Determines the physical address of the SVSM CAA.
+
+  @return The physical address of the SVSM CAA
+
+**/
+UINT64
+EFIAPI
+SvsmGetCaaPa (
+  VOID
+  );
+
+#endif
diff --git a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c 
b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
index 3459338b2033..e4c600d2a46b 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
@@ -44,6 +44,27 @@ SvsmTerminate (
   CpuDeadLoop ();
 }
 
+/**
+  Return the physical address of SVSM Call Area (CAA).
+
+  Determines the physical address of the SVSM CAA.
+
+  @return The physical address of the SVSM CAA
+
+**/
+UINT64
+EFIAPI
+SvsmGetCaaPa (
+  VOID
+  )
+{
+  SVSM_INFORMATION  *SvsmInfo;
+
+  SvsmInfo = (SVSM_INFORMATION *)(UINTN)PcdGet32 (PcdOvmfSnpSecretsBase);
+
+  return CcExitSnpSvsmPresent () ? SvsmInfo->SvsmCaa : 0;
+}
+
 /**
   Return the address of SVSM Call Area (CAA).
 
diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c 
b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
index 0fc30f7bc4f6..950e7c34e37f 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
@@ -1,7 +1,7 @@
 /** @file
   X64 #VC Exception Handler functon.
 
-  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.
+  Copyright (C) 2020 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -18,6 +18,7 @@
 
 #include "CcExitVcHandler.h"
 #include "CcInstruction.h"
+#include "CcExitSvsm.h"
 
 //
 // Non-automatic Exit function prototype
@@ -713,10 +714,29 @@ MsrExit (
   IN CC_INSTRUCTION_DATA *InstructionData
   )
 {
-  UINT64  ExitInfo1, Status;
+  MSR_SVSM_CAA_REGISTER  Msr;
+  UINT64 ExitInfo1;
+  UINT64 Status;
 
   ExitInfo1 = 0;
 
+  //
+  // The SVSM CAA MSR is a software implemented MSR and not supported
+  // by the hardware, handle it directly.
+  //
+  if (Regs->Rax == MSR_SVSM_CAA) {
+// Writes to the SVSM CAA MSR are ignored
+if (*(InstructionData->OpCodes + 1) == 0x30) {
+  return 0;
+}
+
+Msr.Uint64 = SvsmGetCaaPa ();
+Regs->Rax  = Msr.Bits.Lower32Bits;
+Regs->Rdx  = Msr.Bits.Upper32Bits;
+
+return 0;
+  }
+
   switch (*(InstructionData->OpCodes + 1)) {
 case 0x30: // WRMSR
   ExitInfo1  = 1;
@@ -1388,6 +1408,11 @@ GetCpuidFw (
 *Ebx = (*Ebx & 0xFF00) | (Ebx2 & 0x00FF);
 /* node ID */
 *Ecx = (*Ecx & 0xFF00) | (Ecx2 & 0x00FF);
+  } else if (EaxIn == 0x801F) {
+/* Set the SVSM feature bit if running under an SVSM */
+if (CcExitSnpSvsmPresent ()) {
+  *Eax |= BIT28;
+}
   }
 
 Out:
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114641): https://edk2.groups.io/g/devel/message/114641
Mute This Topic: https://groups.io/mt/103986477/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 14/16] UefiCpuPkg/MpInitLib: AP creation support under an SVSM

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When running under an SVSM, the VMPL level of the APs that are started
must match the VMPL level provided by the SVSM. Additionally, each AP
must have a Calling Area for use with the SVSM protocol. Update the AP
creation to properly support running under an SVSM.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index 6186a8d71521..9b00c945e13d 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -55,6 +55,7 @@ SevSnpPerformApAction (
   }
 
   ExitInfo1  = (UINT64)ApicId << 32;
+  ExitInfo1 |= (UINT64)SaveArea->Vmpl << 16;
   ExitInfo1 |= Action;
   ExitInfo2  = (UINT64)(UINTN)SaveArea;
 
@@ -115,6 +116,7 @@ SevSnpCreateSaveArea (
   UINT32  ApicId
   )
 {
+  UINTN PageCount;
   UINT8 *Pages;
   SEV_ES_SAVE_AREA  *SaveArea;
   IA32_CR0  ApCr0;
@@ -124,13 +126,18 @@ SevSnpCreateSaveArea (
   UINTN StartIp;
   UINT8 SipiVector;
 
+  //
+  // When running under an SVSM, a Calling Area page is also needed
+  //
+  PageCount = CcExitSnpSvsmPresent () ? 2 : 1;
+
   if (CpuData->SevEsSaveArea == NULL) {
 //
 // Allocate a page for the SEV-ES Save Area and initialize it. Due to AMD
 // erratum #1467 (VMSA cannot be on a 2MB boundary), allocate an extra page
 // to choose from to work around the issue.
 //
-Pages = AllocateReservedPages (2);
+Pages = AllocateReservedPages (PageCount + 1);
 if (!Pages) {
   return;
 }
@@ -139,12 +146,12 @@ SevSnpCreateSaveArea (
 // Since page allocation works by allocating downward in the address space,
 // try to always free the first (lower address) page to limit possible 
holes
 // in the memory map. So, if the address of the second page is 2MB aligned,
-// then use the first page and free the second page. Otherwise, free the
+// then use the first page and free the last page. Otherwise, free the
 // first page and use the second page.
 //
 if (_IS_ALIGNED (Pages + EFI_PAGE_SIZE, SIZE_2MB)) {
   SaveArea = (SEV_ES_SAVE_AREA *)Pages;
-  FreePages (Pages + EFI_PAGE_SIZE, 1);
+  FreePages (Pages + (EFI_PAGE_SIZE * PageCount), 1);
 } else {
   SaveArea = (SEV_ES_SAVE_AREA *)(Pages + EFI_PAGE_SIZE);
   FreePages (Pages, 1);
@@ -162,7 +169,7 @@ SevSnpCreateSaveArea (
 }
   }
 
-  ZeroMem (SaveArea, EFI_PAGE_SIZE);
+  ZeroMem (SaveArea, EFI_PAGE_SIZE * PageCount);
 
   //
   // Propogate the CR0.NW and CR0.CD setting to the AP
@@ -238,10 +245,10 @@ SevSnpCreateSaveArea (
 
   //
   // Set the SEV-SNP specific fields for the save area:
-  //   VMPL - always VMPL0
+  //   VMPL - based on current mode
   //   SEV_FEATURES - equivalent to the SEV_STATUS MSR right shifted 2 bits
   //
-  SaveArea->Vmpl= 0;
+  SaveArea->Vmpl= CcExitSnpGetVmpl ();
   SaveArea->SevFeatures = AsmReadMsr64 (MSR_SEV_STATUS) >> 2;
 
   SevSnpPerformApAction (SaveArea, ApicId, SVM_VMGEXIT_SNP_AP_CREATE);
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114640): https://edk2.groups.io/g/devel/message/114640
Mute This Topic: https://groups.io/mt/103986475/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 13/16] UefiCpuPkg/MpInitLib: Always use AP Create if PcdSevSnpApicIds is set

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Currently, the first time an AP is started for an SEV-SNP guest, it relies
on the VMSA as set by the hypervisor. If the list of APIC IDs has been
retrieved, this is not necessary. Instead, use the SEV-SNP AP Create
protocol to start the AP for the first time and thereafter using the VMPL
at which the BSP is running.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  1 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |  3 +-
 UefiCpuPkg/Library/MpInitLib/MpLib.h  | 13 
 UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c| 19 +
 UefiCpuPkg/Library/MpInitLib/MpLib.c  |  7 +-
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 79 +++-
 6 files changed, 116 insertions(+), 6 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 55e46d4a1fad..1ec50481f0d4 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -82,6 +82,7 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures  ## 
CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase   ## 
SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi## 
CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpApicIds   ## 
CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard  ## 
CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase   ## 
CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr   ## 
CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index bc3d716aa951..f0af07d3bdfb 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -66,7 +66,8 @@ [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate   ## 
SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase   ## 
SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures  ## CONSUMES
-  gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpApicIds   ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase   ## CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr   ## CONSUMES
 
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 6e2137cb17cd..f1a5fa98d425 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -897,6 +897,19 @@ SevSnpCreateAP (
   IN INTN ProcessorNumber
   );
 
+/**
+  Determine if the SEV-SNP AP Create protocol should be used.
+
+  @param[in]  CpuMpData  Pointer to CPU MP Data
+
+  @retval TRUE   Use SEV-SNP AP Create protocol
+  @retval FALSE  Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+SevSnpUseCreateAP (
+  IN  CPU_MP_DATA  *CpuMpData
+  );
+
 /**
   Get pointer to CPU MP Data structure from GUIDed HOB.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index a2b8a5b3f516..f9f24bee09de 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
@@ -48,3 +48,22 @@ SevSnpCreateAP (
   //
   ASSERT (FALSE);
 }
+
+/**
+  Determine if the SEV-SNP AP Create protocol should be used.
+
+  @param[in]  CpuMpData  Pointer to CPU MP Data
+
+  @retval TRUE   Use SEV-SNP AP Create protocol
+  @retval FALSE  Do not use SEV-SNP AP Create protocol
+**/
+BOOLEAN
+SevSnpUseCreateAP (
+  IN  CPU_MP_DATA  *CpuMpData
+  )
+{
+  //
+  // SEV-SNP is not supported on 32-bit build.
+  //
+  return FALSE;
+}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c 
b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index cdfb570e61a0..5e017bcf9018 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1302,9 +1302,10 @@ WakeUpAP (
   //
   // Wakeup all APs
   //   Must use the INIT-SIPI-SIPI method for initial configuration in
-  //   order to obtain the APIC ID.
+  //   order to obtain the APIC ID if not an SEV-SNP guest and the
+  //   list of APIC IDs is not available.
   //
-  if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != ApInitConfig)) 
{
+  if (SevSnpUseCreateAP (CpuMpData)) {
 SevSnpCreateAP (CpuMpData, -1);
   } else {
 if ((CpuMpData->InitFlag == ApInitConfig) && FixedPcdGetBool 
(PcdFirstTimeWakeUpAPsBySipi)) {
@@ -1414,7 +1415,7 @@ WakeUpAP (
 SetSevEsJumpTable (ExchangeInfo->BufferStart);
   }
 
-  if (CpuMpData->SevSnpIsEnabled && (CpuMpData->InitFlag != 

[edk2-devel] [PATCH 12/16] OvmfPkg/PlatformPei: Retrieve APIC IDs from the hypervisor

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

If the hypervisor supports retrieval of the vCPU APIC IDs, retrieve
them before any APs are actually started. The APIC IDs can be used
to start the APs for any SEV-SNP guest, but is a requirement for an
SEV-SNP guest that is running under an SVSM.

After retrieving the APIC IDs, save the address of the APIC ID data
structure in the PcdSevSnpApicIds PCD.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/PlatformPei/PlatformPei.inf |  1 +
 OvmfPkg/PlatformPei/AmdSev.c| 87 
 2 files changed, 88 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index 6907cc72669e..6379f66b627d 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -116,6 +116,7 @@ [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr
   gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures
   gEfiMdeModulePkgTokenSpaceGuid.PcdTdxSharedBitMask
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpApicIds
 
 [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index af832d3e535e..d8a30b6e1613 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -31,6 +31,85 @@ GetHypervisorFeature (
   VOID
   );
 
+/**
+  Retrieve APIC IDs from the hypervisor.
+
+**/
+STATIC
+VOID
+AmdSevSnpGetApicIds (
+  VOID
+  )
+{
+  MSR_SEV_ES_GHCB_REGISTER  Msr;
+  GHCB  *Ghcb;
+  BOOLEAN   InterruptState;
+  UINT64VmgExitStatus;
+  UINT64PageCount;
+  BOOLEAN   PageCountValid;
+  VOID  *ApicIds;
+  RETURN_STATUS Status;
+
+  Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
+  Ghcb= Msr.Ghcb;
+
+  PageCount  = 0;
+  PageCountValid = FALSE;
+
+  CcExitVmgInit (Ghcb, );
+  Ghcb->SaveArea.Rax = PageCount;
+  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, 0, 0);
+  if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
+PageCount  = Ghcb->SaveArea.Rax;
+PageCountValid = TRUE;
+  }
+
+  CcExitVmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  ASSERT (PageCountValid);
+  if ((VmgExitStatus != 0) || !PageCountValid) {
+return;
+  }
+
+  //
+  // Allocate the memory for the APIC IDs
+  //
+  ApicIds = AllocateReservedPages ((UINTN)PageCount);
+  ASSERT (ApicIds != NULL);
+
+  Status = MemEncryptSevClearPageEncMask (
+ 0,
+ (UINTN)ApicIds,
+ (UINTN)PageCount
+ );
+  ASSERT_RETURN_ERROR (Status);
+
+  ZeroMem (ApicIds, EFI_PAGES_TO_SIZE ((UINTN)PageCount));
+
+  PageCountValid = FALSE;
+
+  CcExitVmgInit (Ghcb, );
+  Ghcb->SaveArea.Rax = PageCount;
+  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
+  VmgExitStatus = CcExitVmgExit (Ghcb, SVM_EXIT_GET_APIC_IDS, (UINTN)ApicIds, 
0);
+  if (CcExitVmgIsOffsetValid (Ghcb, GhcbRax) && (Ghcb->SaveArea.Rax == 
PageCount)) {
+PageCountValid = TRUE;
+  }
+
+  CcExitVmgDone (Ghcb, InterruptState);
+
+  ASSERT (VmgExitStatus == 0);
+  ASSERT (PageCountValid);
+  if ((VmgExitStatus != 0) || !PageCountValid) {
+FreePages (ApicIds, (UINTN)PageCount);
+return;
+  }
+
+  Status = PcdSet64S (PcdSevSnpApicIds, (UINTN)ApicIds);
+}
+
 /**
   Initialize SEV-SNP support if running as an SEV-SNP guest.
 
@@ -78,6 +157,14 @@ AmdSevSnpInitialize (
   }
 }
   }
+
+  //
+  // Retrieve the APIC IDs if the hypervisor supports it. These will be used
+  // to always start APs using SNP AP Create.
+  //
+  if ((HvFeatures & GHCB_HV_FEATURES_APIC_ID_LIST) == 
GHCB_HV_FEATURES_APIC_ID_LIST) {
+AmdSevSnpGetApicIds ();
+  }
 }
 
 /**
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114638): https://edk2.groups.io/g/devel/message/114638
Mute This Topic: https://groups.io/mt/103986465/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 11/16] UefiCpuPkg: Create APIC ID list PCD

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

Create a PCD that can be used to set and get the APIC ID information that
is required for starting APs when an SVSM is present.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/UefiCpuPkg.dec | 7 ++-
 UefiCpuPkg/UefiCpuPkg.uni | 3 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 571b59b36f0a..5ffab58189d9 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -2,7 +2,7 @@
 # This Package provides UEFI compatible CPU modules and libraries.
 #
 # Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights 
reserved.
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -477,5 +477,10 @@ [PcdsDynamic, PcdsDynamicEx]
   # @Prompt GHCB Hypervisor Features
   gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x6018
 
+  ## This dynamic PCD contains the address of the APIC ID list obtained 
through the GHCB GET APIC IDS
+  #  VMGEXIT defined in the version 3 of GHCB spec.
+  # @Prompt SEV-ES CPU APIC ID List
+  gUefiCpuPkgTokenSpaceGuid.PcdSevSnpApicIds|0x0|UINT64|0x601A
+
 [UserExtensions.TianoCore."ExtraFiles"]
   UefiCpuPkgExtra.uni
diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni
index d17bcfd10c7a..329255a0efd4 100644
--- a/UefiCpuPkg/UefiCpuPkg.uni
+++ b/UefiCpuPkg/UefiCpuPkg.uni
@@ -301,3 +301,6 @@
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaSize_PROMPT  #language 
en-US "Specify the size of the SEV-ES work area"
 
 #string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevEsWorkAreaSize_HELP#language 
en-US "Specifies the size of the work area used by an SEV-ES guest."
+
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevSnpApicIds_PROMPT  #language 
en-US "Specifies the address of the APIC ID list."
+#string STR_gUefiCpuPkgTokenSpaceGuid_PcdSevSnpApicIds_HELP#language 
en-US "Set to the address of the APIC ID list retrieved from the hypervisor, 
zero if unavailable."
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114637): https://edk2.groups.io/g/devel/message/114637
Mute This Topic: https://groups.io/mt/103986462/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 10/16] MdePkg: GHCB APIC ID retrieval support definitions

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

When an SVSM is present, starting the APs requires knowledge of the APIC
IDs. Create the definitions required to retrieve and hold the APIC ID
information of all the vCPUs present in the guest.

Signed-off-by: Tom Lendacky 
---
 MdePkg/Include/Register/Amd/Ghcb.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/MdePkg/Include/Register/Amd/Ghcb.h 
b/MdePkg/Include/Register/Amd/Ghcb.h
index 29b2e45d0163..cb581b14723d 100644
--- a/MdePkg/Include/Register/Amd/Ghcb.h
+++ b/MdePkg/Include/Register/Amd/Ghcb.h
@@ -56,6 +56,7 @@
 #define SVM_EXIT_AP_JUMP_TABLE  0x8005ULL
 #define SVM_EXIT_SNP_PAGE_STATE_CHANGE  0x8010ULL
 #define SVM_EXIT_SNP_AP_CREATION0x8013ULL
+#define SVM_EXIT_GET_APIC_IDS   0x8017ULL
 #define SVM_EXIT_HYPERVISOR_FEATURES0x8000FFFDULL
 #define SVM_EXIT_UNSUPPORTED0x8000ULL
 
@@ -170,6 +171,7 @@ typedef union {
 #define GHCB_HV_FEATURES_SNP_AP_CREATE   (GHCB_HV_FEATURES_SNP 
| BIT1)
 #define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION
(GHCB_HV_FEATURES_SNP_AP_CREATE | BIT2)
 #define GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION_TIMER  
(GHCB_HV_FEATURES_SNP_RESTRICTED_INJECTION | BIT3)
+#define GHCB_HV_FEATURES_APIC_ID_LISTBIT4
 
 //
 // SNP Page State Change.
@@ -203,6 +205,14 @@ typedef struct {
 #define SNP_PAGE_STATE_MAX_ENTRY   \
   ((sizeof (((GHCB *)0)->SharedBuffer) - sizeof (SNP_PAGE_STATE_HEADER)) / 
sizeof (SNP_PAGE_STATE_ENTRY))
 
+//
+// Get APIC IDs
+//
+typedef struct {
+  UINT32NumEntries;
+  UINT32ApicIds[];
+} GHCB_APIC_IDS;
+
 //
 // SEV-ES save area mapping structures used for SEV-SNP AP Creation.
 // Only the fields required to be set to a non-zero value are defined.
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114636): https://edk2.groups.io/g/devel/message/114636
Mute This Topic: https://groups.io/mt/103986461/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 09/16] UefiCpuPkg/MpInitLib: Use CcExitSnpVmsaRmpAdjust() to set/clear VMSA

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to change the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. When an
SVSM is present, use the SVSM_CORE_CREATE_VCPU and SVSM_CORE_DELTE_VCPU
calls to change the VMSA attribute on a page instead of issuing the
RMPADJUST instruction directly.

Implement the CcExitSnpVmsaRmpAdjust() API to perform the appropriate
operation to change the VMSA attribute based on the presence of an SVSM.

Signed-off-by: Tom Lendacky 
---
 UefiCpuPkg/Library/MpInitLib/MpLib.h   | 14 --
 UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c | 20 
 UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c  | 53 +++-
 3 files changed, 6 insertions(+), 81 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h 
b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index a96a6389c17d..6e2137cb17cd 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -870,20 +870,6 @@ FillExchangeInfoDataSevEs (
   IN volatile MP_CPU_EXCHANGE_INFO  *ExchangeInfo
   );
 
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  );
-
 /**
   Create an SEV-SNP AP save area (VMSA) for use in running the vCPU.
 
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
index c83144285b68..a2b8a5b3f516 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/AmdSev.c
@@ -48,23 +48,3 @@ SevSnpCreateAP (
   //
   ASSERT (FALSE);
 }
-
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  )
-{
-  //
-  // RMPADJUST is not supported in 32-bit mode
-  //
-  return RETURN_UNSUPPORTED;
-}
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c 
b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
index c9f0984f41a2..db9a37fbbd19 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c
@@ -38,20 +38,15 @@ SevSnpPerformApAction (
   BOOLEAN   InterruptState;
   UINT64ExitInfo1;
   UINT64ExitInfo2;
-  UINT32RmpAdjustStatus;
   UINT64VmgExitStatus;
+  EFI_STATUSVmsaStatus;
 
   if (Action == SVM_VMGEXIT_SNP_AP_CREATE) {
 //
-// To turn the page into a recognized VMSA page, issue RMPADJUST:
-//   Target VMPL but numerically higher than current VMPL
-//   Target PermissionMask is not used
+// Turn the page into a recognized VMSA page.
 //
-RmpAdjustStatus = SevSnpRmpAdjust (
-(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
-TRUE
-);
-if (RmpAdjustStatus != 0) {
+VmsaStatus = CcExitSnpVmsaRmpAdjust (SaveArea, ApicId, TRUE);
+if (EFI_ERROR (VmsaStatus)) {
   DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA creation\n"));
   ASSERT (FALSE);
 
@@ -94,11 +89,8 @@ SevSnpPerformApAction (
 // Make the current VMSA not runnable and accessible to be
 // reprogrammed.
 //
-RmpAdjustStatus = SevSnpRmpAdjust (
-(EFI_PHYSICAL_ADDRESS)(UINTN)SaveArea,
-FALSE
-);
-if (RmpAdjustStatus != 0) {
+VmsaStatus = CcExitSnpVmsaRmpAdjust (SaveArea, ApicId, FALSE);
+if (EFI_ERROR (VmsaStatus)) {
   DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed for VMSA reset\n"));
   ASSERT (FALSE);
 
@@ -292,36 +284,3 @@ SevSnpCreateAP (
 SevSnpCreateSaveArea (CpuMpData, CpuData, ApicId);
   }
 }
-
-/**
-  Issue RMPADJUST to adjust the VMSA attribute of an SEV-SNP page.
-
-  @param[in]  PageAddress
-  @param[in]  VmsaPage
-
-  @return  RMPADJUST return value
-**/
-UINT32
-SevSnpRmpAdjust (
-  IN  EFI_PHYSICAL_ADDRESS  PageAddress,
-  IN  BOOLEAN   VmsaPage
-  )
-{
-  UINT64  Rdx;
-
-  //
-  // The RMPADJUST instruction is used to set or clear the VMSA bit for a
-  // page. The VMSA change is only made when running at VMPL0 and is ignored
-  // otherwise. If too low a target VMPL is specified, the instruction can
-  // succeed without changing the VMSA bit when not running at VMPL0. Using a
-  // target VMPL level of 1, RMPADJUST will return a FAIL_PERMISSION error if
-  // not running at VMPL0, thus ensuring that the VMSA bit is set appropriately
-  // when no error is returned.
-  //
-  Rdx = 1;
-  if (VmsaPage) {
-Rdx |= RMPADJUST_VMSA_PAGE_BIT;
-  }
-
-  return AsmRmpAdjust ((UINT64)PageAddress, 0, Rdx);
-}
-- 
2.42.0




[edk2-devel] [PATCH 08/16] OvmfPkg/CcExitLib: Add support for the SVSM create/delete vCPU calls

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The RMPADJUST instruction is used to alter the VMSA attribute of a page,
but the VMSA attribute can only be changed when running at VMPL0. When
an SVSM is present, use the SVSM_CORE_CREATE_VCPU and SVSM_CORE_DELTE_VCPU
calls to add or remove the VMSA attribute on a page instead of issuing
the RMPADJUST instruction directly.

Implement the CcExitSnpVmsaRmpAdjust() API to perform the proper operation
to update the VMSA attribute.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/CcExitLib/CcExitSvsm.c | 100 +++-
 1 file changed, 99 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c 
b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
index 43e0a357efa5..3459338b2033 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
@@ -137,6 +137,103 @@ SvsmMsrProtocol (
   return Ret;
 }
 
+/**
+  Perform an RMPADJUST operation to alter the VMSA setting of a page.
+
+  Add or remove the VMSA attribute for a page.
+
+  @param[in]   Vmsa   Pointer to an SEV-ES save area page
+  @param[in]   ApicId APIC ID associated with the VMSA
+  @param[in]   SetVmsaBoolean indicator as to whether to set or
+  or clear the VMSA setting for the page
+
+  @retval  EFI_SUCCESSRMPADJUST operation successful
+  @retval  EFI_UNSUPPORTEDOperation is not supported
+  @retval  EFI_INVALID_PARAMETER  RMPADJUST operation failed, an invalid
+  parameter was supplied
+
+**/
+EFI_STATUS
+EFIAPI
+SvsmVmsaRmpAdjust (
+  IN SEV_ES_SAVE_AREA  *Vmsa,
+  IN UINT32ApicId,
+  IN BOOLEAN   SetVmsa
+  )
+{
+  SVSM_CALL_DATA  SvsmCallData;
+  SVSM_FUNCTION   Function;
+  UINTN   Ret;
+
+  SvsmCallData.Caa = SvsmGetCaa ();
+
+  Function.Id.Protocol = 0;
+
+  if (SetVmsa) {
+Function.Id.CallId = 2;
+
+SvsmCallData.RaxIn = Function.Uint64;
+SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+SvsmCallData.RdxIn = (UINT64)(UINTN)Vmsa + SIZE_4KB;
+SvsmCallData.R8In  = ApicId;
+  } else {
+Function.Id.CallId = 3;
+
+SvsmCallData.RaxIn = Function.Uint64;
+SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
+  }
+
+  Ret = SvsmMsrProtocol ();
+
+  return (Ret == 0) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+}
+
+/**
+  Perform an RMPADJUST operation to alter the VMSA setting of a page.
+
+  Add or remove the VMSA attribute for a page.
+
+  @param[in]   Vmsa   Pointer to an SEV-ES save area page
+  @param[in]   ApicId APIC ID associated with the VMSA
+  @param[in]   SetVmsaBoolean indicator as to whether to set or
+  or clear the VMSA setting for the page
+
+  @retval  EFI_SUCCESSRMPADJUST operation successful
+  @retval  EFI_UNSUPPORTEDOperation is not supported
+  @retval  EFI_INVALID_PARAMETER  RMPADJUST operation failed, an invalid
+  parameter was supplied
+
+**/
+EFI_STATUS
+EFIAPI
+BaseVmsaRmpAdjust (
+  IN SEV_ES_SAVE_AREA  *Vmsa,
+  IN UINT32ApicId,
+  IN BOOLEAN   SetVmsa
+  )
+{
+  UINT64  Rdx;
+  UINT32  Ret;
+
+  //
+  // The RMPADJUST instruction is used to set or clear the VMSA bit for a
+  // page. The VMSA change is only made when running at VMPL0 and is ignored
+  // otherwise. If too low a target VMPL is specified, the instruction can
+  // succeed without changing the VMSA bit when not running at VMPL0. Using a
+  // target VMPL level of 1, RMPADJUST will return a FAIL_PERMISSION error if
+  // not running at VMPL0, thus ensuring that the VMSA bit is set appropriately
+  // when no error is returned.
+  //
+  Rdx = 1;
+  if (SetVmsa) {
+Rdx |= RMPADJUST_VMSA_PAGE_BIT;
+  }
+
+  Ret = AsmRmpAdjust ((UINT64)(UINTN)Vmsa, 0, Rdx);
+
+  return (Ret == 0) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+}
+
 /**
   Issue an SVSM request to perform the PVALIDATE instruction.
 
@@ -409,5 +506,6 @@ CcExitSnpVmsaRmpAdjust (
   IN BOOLEAN   SetVmsa
   )
 {
-  return EFI_UNSUPPORTED;
+  return CcExitSnpSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa)
+ : BaseVmsaRmpAdjust (Vmsa, ApicId, SetVmsa);
 }
-- 
2.42.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114634): https://edk2.groups.io/g/devel/message/114634
Mute This Topic: https://groups.io/mt/103986458/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




[edk2-devel] [PATCH 07/16] OvmfPkg/CcExitLib: Add support for the SVSM_CORE_PVALIDATE call

2024-01-26 Thread Lendacky, Thomas via groups.io
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654

The PVALIDATE instruction can only be performed at VMPL0. An SVSM will
be present when running at VMPL1 or higher.

When an SVSM is present, use the SVSM_CORE_PVALIDATE call to perform
memory validation instead of issuing the PVALIDATE instruction directly.
This moves the current PVALIDATE functionality into the CcExitLib library,
where it can be determined whether an SVSM is present and perform the
proper operation.

Signed-off-by: Tom Lendacky 
---
 OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c |  82 
+-
 OvmfPkg/Library/CcExitLib/CcExitSvsm.c| 311 

 2 files changed, 321 insertions(+), 72 deletions(-)

diff --git 
a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index f8bbe4d6f46b..60d47ce090fe 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -17,11 +17,10 @@
 
 #include 
 #include 
+#include 
 
 #include "SnpPageStateChange.h"
 
-#define PAGES_PER_LARGE_ENTRY  512
-
 STATIC
 UINTN
 MemoryStateToGhcbOp (
@@ -63,73 +62,6 @@ SnpPageStateFailureTerminate (
   CpuDeadLoop ();
 }
 
-/**
- This function issues the PVALIDATE instruction to validate or invalidate the 
memory
- range specified. If PVALIDATE returns size mismatch then it retry validating 
with
- smaller page size.
-
- */
-STATIC
-VOID
-PvalidateRange (
-  IN  SNP_PAGE_STATE_CHANGE_INFO  *Info
-  )
-{
-  UINTN RmpPageSize;
-  UINTN StartIndex;
-  UINTN EndIndex;
-  UINTN Index;
-  UINTN Ret;
-  EFI_PHYSICAL_ADDRESS  Address;
-  BOOLEAN   Validate;
-
-  StartIndex = Info->Header.CurrentEntry;
-  EndIndex   = Info->Header.EndEntry;
-
-  for ( ; StartIndex <= EndIndex; StartIndex++) {
-//
-// Get the address and the page size from the Info.
-//
-Address = 
((EFI_PHYSICAL_ADDRESS)Info->Entry[StartIndex].GuestFrameNumber) << 
EFI_PAGE_SHIFT;
-RmpPageSize = Info->Entry[StartIndex].PageSize;
-Validate= Info->Entry[StartIndex].Operation == SNP_PAGE_STATE_PRIVATE;
-
-Ret = AsmPvalidate (RmpPageSize, Validate, Address);
-
-//
-// If we fail to validate due to size mismatch then try with the
-// smaller page size. This senario will occur if the backing page in
-// the RMP entry is 4K and we are validating it as a 2MB.
-//
-if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == 
PvalidatePageSize2MB)) {
-  for (Index = 0; Index < PAGES_PER_LARGE_ENTRY; Index++) {
-Ret = AsmPvalidate (PvalidatePageSize4K, Validate, Address);
-if (Ret) {
-  break;
-}
-
-Address = Address + EFI_PAGE_SIZE;
-  }
-}
-
-//
-// If validation failed then do not continue.
-//
-if (Ret) {
-  DEBUG ((
-DEBUG_ERROR,
-"%a:%a: Failed to %a address 0x%Lx Error code %d\n",
-gEfiCallerBaseName,
-__func__,
-Validate ? "Validate" : "Invalidate",
-Address,
-Ret
-));
-  SnpPageStateFailureTerminate ();
-}
-  }
-}
-
 STATIC
 EFI_PHYSICAL_ADDRESS
 BuildPageStateBuffer (
@@ -145,6 +77,7 @@ BuildPageStateBuffer (
   UINTN Index;
   UINTN IndexMax;
   UINTN PscIndexMax;
+  UINTN SvsmIndexMax;
   UINTN RmpPageSize;
 
   // Clear the page state structure
@@ -159,11 +92,16 @@ BuildPageStateBuffer (
   // exiting from the guest to the hypervisor. Maximize the number of entries
   // that can be processed per exit.
   //
-  PscIndexMax = (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * 
SNP_PAGE_STATE_MAX_ENTRY;
+  PscIndexMax  = (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * 
SNP_PAGE_STATE_MAX_ENTRY;
+  SvsmIndexMax = (IndexMax / SVSM_PVALIDATE_MAX_ENTRY) * 
SVSM_PVALIDATE_MAX_ENTRY;
   if (PscIndexMax > 0) {
 IndexMax = MIN (IndexMax, PscIndexMax);
   }
 
+  if (SvsmIndexMax > 0) {
+IndexMax = MIN (IndexMax, SvsmIndexMax);
+  }
+
   //
   // Populate the page state entry structure
   //
@@ -328,7 +266,7 @@ InternalSetPageState (
 // invalidate the pages before making the page shared in the RMP table.
 //
 if (State == SevSnpPageShared) {
-  PvalidateRange (Info);
+  CcExitSnpPvalidate (Info);
 }
 
 //
@@ -341,7 +279,7 @@ InternalSetPageState (
 // validate the pages after it has been added in the RMP table.
 //
 if (State == SevSnpPagePrivate) {
-  PvalidateRange (Info);
+  CcExitSnpPvalidate (Info);
 }
   }
 }
diff --git a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c 
b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
index fb8b762caadc..43e0a357efa5 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitSvsm.c
@@ -13,6 +13,312 

  1   2   3   4   >