Re: [edk2-devel] [PATCH 0/2] AmdSev: Harden SEV Kernel hashes verifier

2024-06-27 Thread Tobin Feldman-Fitzthum




On 6/26/24 10:33 AM, Aithal, Srikanth wrote:


On 6/26/2024 7:28 PM, Tobin Feldman-Fitzthum wrote:



On 6/26/24 4:08 AM, Aithal, Srikanth wrote:
Hello, SEV/SEVES guest boot fails with AMDSEV OVMF package built 
using upstream edk2 master [commit head: 
2fbaaa96d11ad61a9133df1728e3fe965d1457a5]. SEV/SEVES guest boot with 
AMDSEV package gets stuck at below point: Plain Text 2024-06-26 04: 
 38:  02: 



Hello,

SEV/SEVES guest boot fails with AMDSEV OVMF package built using 
upstream edk2 master [commit 
head: 2fbaaa96d11ad61a9133df1728e3fe965d1457a5].


SEV/SEVES guest boot with AMDSEV package gets stuck at below point:

Plain Text

|2024-06-26 04:38:02: FetchBlob: loading 14332416 bytes for "kernel" 
2024-06-26 04:38:02: Select Item: 0x18 2024-06-26 04:38:02: Select 
Item: 0x11 2024-06-26 04:38:02: VerifyBlob: Found GUID 
4DE79437-ABD2-427F-B835-D5B172D2045B in table 2024-06-26 04:38:02: 
VerifyBlob: Hash comparison succeeded for "kernel" 2024-06-26 
04:38:02: Select Item: 0xB 2024-06-26 04:38:02: VerifyBlob: Found 
GUID 44BAF731-3A2F-4BD7-9AF1-41E29169781D in table 2024-06-26 
04:38:02: VerifyBlob: Blob Specified in Hash Table was not Provided 
--> Hung here |



Can you send qemu command that produces this case?
It looks like what is happening is that the initrd is specified in the 
hash table, but is not provided to the guest.

You might try with and without the -initrd option and compare.
It's possible that when -initrd is not provided, QEMU will still put 
something in the table, which this patch might not account for.


-Tobin

my qemu command line to recreate the issue:

qemu-system-x86_64 \
-machine q35,confidential-guest-support=sev0,vmport=off \
-object sev-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,kernel-hashes=on \
-name guest=vm,debug-threads=on \
-drive 
if=pflash,format=raw,unit=0,file=/VT_BUILD/OVMF_AmdSev/OVMF.fd,readonly \

-cpu host \
-m 4096 \
-kernel '/VT_BUILD/usr/local/bzImage' \
-append 'root=/dev/sda rw console=ttyS0,115200n8 
earlyprintk=ttyS0,115200 net.ifnames=0 biosdevname=0 movable_node 
swiotlb=65536' \

-smp 1,cores=1,threads=1,dies=1,sockets=1 \
-drive 
file=/VT_BUILD/images/22.04-server.qcow2,index=0,media=disk,format=qcow2 \

--enable-kvm \
--nographic


Yes, if I pass -initrd explicitly the Hash verify step passes properly

FetchBlob: loading 14332416 bytes for "kernel"
Select Item: 0x18
Select Item: 0x11
VerifyBlob: Found GUID 4DE79437-ABD2-427F-B835-D5B172D2045B in table
VerifyBlob: Hash comparison succeeded for "kernel"
Select Item: 0xB
FetchBlob: loading 75379943 bytes for "initrd"
Select Item: 0x12
VerifyBlob: Found GUID 44BAF731-3A2F-4BD7-9AF1-41E29169781D in table
VerifyBlob: Hash comparison succeeded for "initrd"
Select Item: 0x14
FetchBlob: loading 120 bytes for "cmdline"
Select Item: 0x15
VerifyBlob: Found GUID 97D02DD8-BD20-4C94-AA78-E7714D36AB2A in table
VerifyBlob: Hash comparison succeeded for "cmdline"


Ok, I'll submit a little tweak this afternoon that should fix your case.

-Tobin
This was working until yesterday [commit head: be38c01], where we can 
see boot was proceeding


Plain Text

|2024-06-25 03:13:23: VerifyBlob: Found GUID 
4DE79437-ABD2-427F-B835-D5B172D2045B in table 2024-06-25 03:13:23: 
VerifyBlob: Hash comparison succeeded for "kernel" 2024-06-25 
03:13:23: Select Item: 0xB 2024-06-25 03:13:23: VerifyBlob: Found 
GUID 44BAF731-3A2F-4BD7-9AF1-41E29169781D in table 2024-06-25 
03:13:23: VerifyBlob: Hash comparison succeeded for "initrd" 
2024-06-25 03:13:23: Select Item: 0x14 2024-06-25 03:13:23: 
FetchBlob: loading 120 bytes for "cmdline" 2024-06-25 03:13:23: 
Select Item: 0x15 2024-06-25 03:13:23: VerifyBlob: Found GUID 
97D02DD8-BD20-4C94-AA78-E7714D36AB2A in table 2024-06-25 03:13:23: 
VerifyBlob: Hash comparison succeeded for "cmdline"|



After this patch got merged the regression is seen.

Thanks,

Srikanth Aithal


On 5/7/2024 1:57 AM, Tobin Feldman-Fitzthum via groups.io wrote:

The AmdSev package has a so-called BlobVerifier, which
is meant to extend the TCB of a confidential guest
(SEV or SNP) to include components provided via fw_cfg
such as initrd, kernel, kernel params.

This series fixes a few implementation errors in the
blob verifier. One common theme is that the verifier
currently fails to halt the boot when an invalid blob
is detected. This can lead to a confidential guest
having a launch measurement that does not reflect the
guest TCB.

This series could also help us move towards consolidating
the AmdSev package back into the OvmfPkg although more
discussion will be needed on this.

Thank you for Ryan Savino at AMD for pointing out
some of these issues.

Tobin Feldman-Fitzthum (2):
   AmdSev: Rework Blob Verifier
   AmdSev: Halt on failed blob allocation

  .../BlobVerifierSevHashes.c   | 56 
---

  OvmfPkg/Include/Library/BlobVerifierLib.h | 14 +++--
  

Re: [edk2-devel] [PATCH 0/2] AmdSev: Harden SEV Kernel hashes verifier

2024-06-26 Thread Tobin Feldman-Fitzthum




On 6/26/24 4:08 AM, Aithal, Srikanth wrote:
Hello, SEV/SEVES guest boot fails with AMDSEV OVMF package built using 
upstream edk2 master [commit head: 
2fbaaa96d11ad61a9133df1728e3fe965d1457a5]. SEV/SEVES guest boot with 
AMDSEV package gets stuck at below point: Plain Text 2024-06-26 04: 38: 
 02: 



Hello,

SEV/SEVES guest boot fails with AMDSEV OVMF package built using upstream 
edk2 master [commit head: 2fbaaa96d11ad61a9133df1728e3fe965d1457a5].


SEV/SEVES guest boot with AMDSEV package gets stuck at below point:

Plain Text

|2024-06-26 04:38:02: FetchBlob: loading 14332416 bytes for "kernel" 
2024-06-26 04:38:02: Select Item: 0x18 2024-06-26 04:38:02: Select Item: 
0x11 2024-06-26 04:38:02: VerifyBlob: Found GUID 
4DE79437-ABD2-427F-B835-D5B172D2045B in table 2024-06-26 04:38:02: 
VerifyBlob: Hash comparison succeeded for "kernel" 2024-06-26 04:38:02: 
Select Item: 0xB 2024-06-26 04:38:02: VerifyBlob: Found GUID 
44BAF731-3A2F-4BD7-9AF1-41E29169781D in table 2024-06-26 04:38:02: 
VerifyBlob: Blob Specified in Hash Table was not Provided --> Hung here |



Can you send qemu command that produces this case?
It looks like what is happening is that the initrd is specified in the 
hash table, but is not provided to the guest.

You might try with and without the -initrd option and compare.
It's possible that when -initrd is not provided, QEMU will still put 
something in the table, which this patch might not account for.


-Tobin
This was working until yesterday [commit head: be38c01], where we can 
see boot was proceeding


Plain Text

|2024-06-25 03:13:23: VerifyBlob: Found GUID 
4DE79437-ABD2-427F-B835-D5B172D2045B in table 2024-06-25 03:13:23: 
VerifyBlob: Hash comparison succeeded for "kernel" 2024-06-25 03:13:23: 
Select Item: 0xB 2024-06-25 03:13:23: VerifyBlob: Found GUID 
44BAF731-3A2F-4BD7-9AF1-41E29169781D in table 2024-06-25 03:13:23: 
VerifyBlob: Hash comparison succeeded for "initrd" 2024-06-25 03:13:23: 
Select Item: 0x14 2024-06-25 03:13:23: FetchBlob: loading 120 bytes for 
"cmdline" 2024-06-25 03:13:23: Select Item: 0x15 2024-06-25 03:13:23: 
VerifyBlob: Found GUID 97D02DD8-BD20-4C94-AA78-E7714D36AB2A in table 
2024-06-25 03:13:23: VerifyBlob: Hash comparison succeeded for "cmdline"|



After this patch got merged the regression is seen.

Thanks,

Srikanth Aithal


On 5/7/2024 1:57 AM, Tobin Feldman-Fitzthum via groups.io wrote:

The AmdSev package has a so-called BlobVerifier, which
is meant to extend the TCB of a confidential guest
(SEV or SNP) to include components provided via fw_cfg
such as initrd, kernel, kernel params.

This series fixes a few implementation errors in the
blob verifier. One common theme is that the verifier
currently fails to halt the boot when an invalid blob
is detected. This can lead to a confidential guest
having a launch measurement that does not reflect the
guest TCB.

This series could also help us move towards consolidating
the AmdSev package back into the OvmfPkg although more
discussion will be needed on this.

Thank you for Ryan Savino at AMD for pointing out
some of these issues.

Tobin Feldman-Fitzthum (2):
   AmdSev: Rework Blob Verifier
   AmdSev: Halt on failed blob allocation

  .../BlobVerifierSevHashes.c   | 56 ---
  OvmfPkg/Include/Library/BlobVerifierLib.h | 14 +++--
  .../BlobVerifierLibNull/BlobVerifierNull.c| 13 +++--
  .../QemuKernelLoaderFsDxe.c   |  9 ++-
  4 files changed, 69 insertions(+), 23 deletions(-)




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




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

2024-05-08 Thread Tobin Feldman-Fitzthum
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.

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",
   __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
+));
+
+  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;
 }
 
 /**
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118662): https://edk2.groups.io/g/devel/message/118662
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]
-=-=-=-=-=-=-=-=-=-=-=-




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

2024-05-08 Thread Tobin Feldman-Fitzthum
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.
+
   @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 3c12085f6c..cf58c97cd2 100644
--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
+++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
@@ -1042,6 +1042,7 @@ QemuKernelLoaderFsDxeEntrypoint (
   KERNEL_BLOB  *C

[edk2-devel] [PATCH 0/2] AmdSev: Harden SEV Kernel hashes verifier

2024-05-08 Thread Tobin Feldman-Fitzthum
The AmdSev package has a so-called BlobVerifier, which
is meant to extend the TCB of a confidential guest
(SEV or SNP) to include components provided via fw_cfg
such as initrd, kernel, kernel params.

This series fixes a few implementation errors in the
blob verifier. One common theme is that the verifier
currently fails to halt the boot when an invalid blob
is detected. This can lead to a confidential guest
having a launch measurement that does not reflect the
guest TCB.

This series could also help us move towards consolidating
the AmdSev package back into the OvmfPkg although more
discussion will be needed on this.

Thank you for Ryan Savino at AMD for pointing out
some of these issues.

Tobin Feldman-Fitzthum (2):
  AmdSev: Rework Blob Verifier
  AmdSev: Halt on failed blob allocation

 .../BlobVerifierSevHashes.c   | 56 ---
 OvmfPkg/Include/Library/BlobVerifierLib.h | 14 +++--
 .../BlobVerifierLibNull/BlobVerifierNull.c| 13 +++--
 .../QemuKernelLoaderFsDxe.c   |  9 ++-
 4 files changed, 69 insertions(+), 23 deletions(-)

-- 
2.34.1



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




[edk2-devel] [RFC PATCH 8/9] OvmfPkg/AmdSev: Add Migration Handler entry point

2021-08-18 Thread Tobin Feldman-Fitzthum
The Migration Handler runs in the mirror VM. The MH is started
directly by the hypervisor. SetupMigrationHandler runs in the main
VM and sets up the migration entry point. The HV starts execution
of the mirror vCPU at the entry point, which trampolines to
MigrationHandlerMain

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/OvmfPkg.dec   |  3 ++
 OvmfPkg/AmdSev/AmdSevX64.fdf  |  3 ++
 .../ConfidentialMigrationDxe.inf  |  2 +
 .../ConfidentialMigrationPei.inf  |  2 +
 .../ConfidentialMigrationDxe.c| 48 +
 .../ConfidentialMigrationPei.c|  6 +++
 .../MigrationEntryPoint.nasm  | 51 +++
 7 files changed, 115 insertions(+)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/MigrationEntryPoint.nasm

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 1252582c99..c6e07accf6 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -336,6 +336,9 @@
   
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|0x0|UINT32|0x4b
   
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize|0x0|UINT32|0x4c
 
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase|0x0|UINT32|0x4d
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntrySize|0x0|UINT32|0x4e
+
 [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 a8e296e641..8687fadfcc 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -74,6 +74,9 @@ 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.P
 0x02|0x003000
 
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
 
+0x023000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntrySize
+
 0x12|0x0E
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
 FV = PEIFV
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 42875095fc..b879037586 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -16,6 +16,7 @@
 [Sources]
   ConfidentialMigrationDxe.c
   VirtualMemory.h
+  MigrationEntryPoint.nasm
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -31,6 +32,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
   gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
   gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase
 
 [Depex]
   TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
index 918cf22abd..6233b82cc2 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
@@ -30,6 +30,8 @@
 [FixedPcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
   gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntrySize
 
 [Depex]
   TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 2de35a7bb1..5e96206d17 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -38,11 +38,23 @@ typedef volatile struct {
   UINT32   Done;
 } MH_COMMAND_PARAMETERS;
 
+//
+// Addresses to be used in the entry point
+//
+typedef struct {
+  UINT32 Cr3;
+  UINT64 StackBase;
+  UINT64 MhBase;
+} ENTRY_ADDRS;
+
 //
 // Offset for non-cbit mapping.
 //
 #define UNENC_VIRT_ADDR_BASE0xff80ULL
 
+void MigrationHandlerEntryPoint(void);
+void MigrationHandlerEntryPoint64(void);
+
 STATIC PAGE_TABLE_POOL   *mPageTablePool = NULL;
 PHYSICAL_ADDRESS  mMigrationHandlerPageTables = 0;
 PHYSICAL_ADDRESS  mMigrationHandlerStackBase = 0;
@@ -193,6 +205,16 @@ SetupMigrationHandler (
   IN EFI_SYSTEM_TABLE *SystemTable
   )
 {
+  UINT32LongModeOffset;
+  UINT32EntryAddrsOffset;
+  UINT32GdtOffset;
+  IA32_DESCRIPTOR   GdtPtr;
+  UINT64EntryPoint;
+  ENTRY_ADDRS   *EntryData;
+
+  LongModeOffset = 0x200;
+  EntryAddrsOffset = 0x400;
+  GdtOffset = 0x600;
 
   if (!PcdGetBool(PcdStartConfidentialMigrationHandler)) {
 return 0;
@@ -205,6 +227,32

[edk2-devel] [RFC PATCH 9/9] OvmfPkg/ResetVector: Expose Migration Handler Entry Addresses

2021-08-18 Thread Tobin Feldman-Fitzthum
Exposes the address of the Migration Handler entry point via a
GUIDed struct. To support migration, the HV should find this
struct and start one vCPU at the entry point address.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/ResetVector/ResetVector.inf  |  1 +
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 13 +
 OvmfPkg/ResetVector/ResetVector.nasmb|  1 +
 3 files changed, 15 insertions(+)

diff --git a/OvmfPkg/ResetVector/ResetVector.inf 
b/OvmfPkg/ResetVector/ResetVector.inf
index d028c92d8c..642757796c 100644
--- a/OvmfPkg/ResetVector/ResetVector.inf
+++ b/OvmfPkg/ResetVector/ResetVector.inf
@@ -49,3 +49,4 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationEntryBase
diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm 
b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
index 7ec3c6e980..fc38bd927d 100644
--- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
+++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm
@@ -86,6 +86,19 @@ sevSecretBlockStart:
 DB  0x80, 0x81, 0x12, 0x7C, 0x90, 0xD3, 0xD2, 0x94
 sevSecretBlockEnd:
 
+;
+; The IP of the migration handler. The hypervisor should start
+; the mirror with this address.
+;
+; GUID = 5c7db037-ab87-4282-b33c-7894f01471ec
+;
+sevMigrationBlockStart:
+DD  SEV_MIGRATION_ENTRY_IP
+DW  sevMigrationBlockStart - sevMigrationBlockEnd
+DB  0x5C, 0x7D, 0xB0, 0x37, 0x87, 0xAB, 0x82, 0x42
+DB  0xB3, 0x3C, 0x78, 0x94, 0xF0, 0x14, 0x71, 0xEC
+sevMigrationBlockEnd:
+
 ;
 ; SEV-ES Processor Reset support
 ;
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb 
b/OvmfPkg/ResetVector/ResetVector.nasmb
index acec46a324..344713bfbb 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -91,5 +91,6 @@
   %define SEV_LAUNCH_SECRET_SIZE  FixedPcdGet32 (PcdSevLaunchSecretSize)
   %define SEV_FW_HASH_BLOCK_BASE  FixedPcdGet32 (PcdQemuHashTableBase)
   %define SEV_FW_HASH_BLOCK_SIZE  FixedPcdGet32 (PcdQemuHashTableSize)
+  %define SEV_MIGRATION_ENTRY_IP  FixedPcdGet32 
(PcdConfidentialMigrationEntryBase)
 %include "Ia16/ResetVectorVtf0.asm"
 
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 4/9] OvmfPkg/AmdSev: MH support for mailbox protocol

2021-08-18 Thread Tobin Feldman-Fitzthum
The migration handler communicates with the hypervisor
via a shared mailbox page. The MH can perform four functions
at the behest of the HV: init, save page, restore page, and
reset.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.inf  |  1 +
 .../ConfidentialMigrationDxe.c| 74 +++
 2 files changed, 75 insertions(+)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 6e3fa7e51c..cb5609271c 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -29,6 +29,7 @@
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
   gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
 
 [Depex]
   TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index f0dfbd279e..a981aaeac7 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -6,14 +6,88 @@
 **/
 
 #include 
+#include 
 #include 
 
+//
+// Functions implemented by the migration handler
+//
+#define MH_FUNC_INIT  0
+#define MH_FUNC_SAVE_PAGE 1
+#define MH_FUNC_RESTORE_PAGE  2
+#define MH_FUNC_RESET 3
+
+//
+// Return codes for MH functions
+//
+#define MH_SUCCESS0
+#define MH_INVALID_FUNC (-1)
+#define MH_AUTH_ERR (-2)
+
+//
+// Mailbox for communication with hypervisor
+//
+typedef volatile struct {
+  UINT64   Nr;
+  UINT64   Gpa;
+  UINT32   DoPrefetch;
+  UINT32   Ret;
+  UINT32   Go;
+  UINT32   Done;
+} MH_COMMAND_PARAMETERS;
+
+
 VOID
 EFIAPI
 MigrationHandlerMain ()
 {
+  UINT64   MailboxStart;
+  MH_COMMAND_PARAMETERS*Params;
+  VOID *PageVa;
+
   DebugPrint (DEBUG_INFO,"Migration Handler Started\n");
 
+  MailboxStart = PcdGet32 (PcdConfidentialMigrationMailboxBase);
+  Params = (VOID *)MailboxStart;
+  PageVa = (VOID *)(MailboxStart + 0x1000);
+
+  DisableInterrupts ();
+  Params->Go = 0;
+
+  while (1) {
+while (!Params->Go) {
+  CpuPause ();
+}
+Params->Done = 0;
+
+switch (Params->Nr) {
+case MH_FUNC_INIT:
+  Params->Ret = MH_SUCCESS;
+  break;
+
+case MH_FUNC_SAVE_PAGE:
+  CopyMem (PageVa, (VOID *)Params->Gpa, 4096);
+  Params->Ret = MH_SUCCESS;
+  break;
+
+case MH_FUNC_RESTORE_PAGE:
+  CopyMem ((VOID *)Params->Gpa, PageVa, 4096);
+  Params->Ret = MH_SUCCESS;
+  break;
+
+case MH_FUNC_RESET:
+  Params->Ret = MH_SUCCESS;
+  break;
+
+default:
+  Params->Ret = MH_INVALID_FUNC;
+  break;
+}
+
+Params->Go = 0;
+Params->Done = 1;
+
+  }
 }
 
 /**
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 7/9] OvmfPkg/AmdSev: Don't overwrite MH stack

2021-08-18 Thread Tobin Feldman-Fitzthum
The Migration Handler uses its own stack and should avoid
overwriting the stack when importing pages.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.c  | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index ee1466eb00..2de35a7bb1 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -45,6 +45,8 @@ typedef volatile struct {
 
 STATIC PAGE_TABLE_POOL   *mPageTablePool = NULL;
 PHYSICAL_ADDRESS  mMigrationHandlerPageTables = 0;
+PHYSICAL_ADDRESS  mMigrationHandlerStackBase = 0;
+UINT32mMigrationHandlerStackSize = 4;
 
 /**
   Allocates and fills in custom page tables for Migration Handler.
@@ -112,6 +114,8 @@ MigrationHandlerMain ()
   UINT64   MailboxEnd;
   UINT64   PagetableStart;
   UINT64   PagetableEnd;
+  UINT64   StackStart;
+  UINT64   StackEnd;
   MH_COMMAND_PARAMETERS*Params;
   VOID *PageVa;
 
@@ -126,6 +130,9 @@ MigrationHandlerMain ()
   PagetableStart = mMigrationHandlerPageTables;
   PagetableEnd = PagetableStart + 11 * EFI_PAGE_SIZE;
 
+  StackStart = mMigrationHandlerStackBase;
+  StackEnd = StackStart + mMigrationHandlerStackSize;
+
   DisableInterrupts ();
   Params->Go = 0;
 
@@ -147,10 +154,11 @@ MigrationHandlerMain ()
 
 case MH_FUNC_RESTORE_PAGE:
   //
-  // Don't import a page that covers the mailbox or pagetables.
+  // Don't import a page that covers the mailbox, pagetables, or stack.
   //
   if (!((Params->Gpa >= MailboxStart && Params->Gpa < MailboxEnd) ||
-  (Params->Gpa >= PagetableStart && Params->Gpa < PagetableEnd))) {
+  (Params->Gpa >= PagetableStart && Params->Gpa < PagetableEnd) ||
+  (Params->Gpa >= StackStart && Params->Gpa < StackEnd))) {
 
 CopyMem ((VOID *)Params->Gpa, PageVa, 4096);
   }
@@ -190,6 +198,11 @@ SetupMigrationHandler (
 return 0;
   }
 
+  //
+  // Setup stack and pagetables for Migration Handler
+  //
+  mMigrationHandlerStackBase = (UINTN)AllocateAlignedRuntimePages 
(mMigrationHandlerStackSize, PAGE_TABLE_POOL_ALIGNMENT);
+
PrepareMigrationHandlerPageTables ();
 
   //
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 6/9] OvmfPkg/AmdSev: Don't overwrite mailbox or pagetables

2021-08-18 Thread Tobin Feldman-Fitzthum
While restoring pages, the MH should avoid overwriting its
pagetables or the mailbox it uses to communicate with the HV.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.c  | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 34d449fe10..ee1466eb00 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -109,6 +109,9 @@ EFIAPI
 MigrationHandlerMain ()
 {
   UINT64   MailboxStart;
+  UINT64   MailboxEnd;
+  UINT64   PagetableStart;
+  UINT64   PagetableEnd;
   MH_COMMAND_PARAMETERS*Params;
   VOID *PageVa;
 
@@ -118,6 +121,11 @@ MigrationHandlerMain ()
   Params = (VOID *)(MailboxStart + UNENC_VIRT_ADDR_BASE);
   PageVa = (VOID *)(MailboxStart + UNENC_VIRT_ADDR_BASE + 0x1000);
 
+  MailboxEnd = MailboxStart + 2 * EFI_PAGE_SIZE;
+
+  PagetableStart = mMigrationHandlerPageTables;
+  PagetableEnd = PagetableStart + 11 * EFI_PAGE_SIZE;
+
   DisableInterrupts ();
   Params->Go = 0;
 
@@ -138,7 +146,14 @@ MigrationHandlerMain ()
   break;
 
 case MH_FUNC_RESTORE_PAGE:
-  CopyMem ((VOID *)Params->Gpa, PageVa, 4096);
+  //
+  // Don't import a page that covers the mailbox or pagetables.
+  //
+  if (!((Params->Gpa >= MailboxStart && Params->Gpa < MailboxEnd) ||
+  (Params->Gpa >= PagetableStart && Params->Gpa < PagetableEnd))) {
+
+CopyMem ((VOID *)Params->Gpa, PageVa, 4096);
+  }
   Params->Ret = MH_SUCCESS;
   break;
 
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 5/9] OvmfPkg/AmdSev: Build page table for migration handler

2021-08-18 Thread Tobin Feldman-Fitzthum
From: Dov Murik 

The migration handler builds its own page tables and switches
to them. The MH pagetables are reserved as runtime memory.

When the hypervisor asks the MH to import/export a page, the HV
writes the guest physical address of the page in question to the
mailbox. The MH uses an identity mapping so that it can read/write
whatever GPA is requested by the HV. The hypervisor only asks the
MH to import/export encrypted pages. Thus, the C-Bit can be set
for every page in the identity map.

The MH also needs to read shared pages, such as the mailbox.
These are mapped at an offset. The offset must be added to
the physical address before it can be resolved.

Signed-off-by: Tobin Feldman-Fitzthum 
Signed-off-by: Dov Murik 
---
 .../ConfidentialMigrationDxe.inf  |   1 +
 .../ConfidentialMigration/VirtualMemory.h | 177 ++
 .../ConfidentialMigrationDxe.c|  73 +++-
 3 files changed, 249 insertions(+), 2 deletions(-)
 create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index cb5609271c..42875095fc 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -15,6 +15,7 @@
 
 [Sources]
   ConfidentialMigrationDxe.c
+  VirtualMemory.h
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h 
b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
new file mode 100644
index 00..c50cb64c63
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
@@ -0,0 +1,177 @@
+/** @file
+  Virtual Memory Management Services to set or clear the memory encryption bit
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+  Copyright (c) 2017, AMD Incorporated. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+  Code is derived from OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
+
+**/
+
+#ifndef __VIRTUAL_MEMORY__
+#define __VIRTUAL_MEMORY__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SYS_CODE64_SEL 0x38
+
+#pragma pack(1)
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+typedef union {
+  struct {
+UINT64  Present:1;// 0 = Not present in memory,
+  //   1 = Present in memory
+UINT64  ReadWrite:1;  // 0 = Read-Only, 1= Read/Write
+UINT64  UserSupervisor:1; // 0 = Supervisor, 1=User
+UINT64  WriteThrough:1;   // 0 = Write-Back caching,
+  //   1 = Write-Through caching
+UINT64  CacheDisabled:1;  // 0 = Cached, 1=Non-Cached
+UINT64  Accessed:1;   // 0 = Not accessed,
+  //   1 = Accessed (set by CPU)
+UINT64  Reserved:1;   // Reserved
+UINT64  MustBeZero:2; // Must Be Zero
+UINT64  Available:3;  // Available for use by system software
+UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+UINT64  AvabilableHigh:11;// Available for use by system software
+UINT64  Nx:1; // No Execute bit
+  } Bits;
+  UINT64Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 4KB
+//
+typedef union {
+  struct {
+UINT64  Present:1;// 0 = Not present in memory,
+  //   1 = Present in memory
+UINT64  ReadWrite:1;  // 0 = Read-Only, 1= Read/Write
+UINT64  UserSupervisor:1; // 0 = Supervisor, 1=User
+UINT64  WriteThrough:1;   // 0 = Write-Back caching,
+  //   1 = Write-Through caching
+UINT64  CacheDisabled:1;  // 0 = Cached, 1=Non-Cached
+UINT64  Accessed:1;   // 0 = Not accessed,
+  //   1 = Accessed (set by CPU)
+UINT64  Dirty:1;  // 0 = Not Dirty, 1 = written by
+  //   processor on access to page
+UINT64  PAT:1;//
+UINT64  Global:1; // 0 = Not global page, 1 = global page
+  //   TLB not cleared on CR3 write
+UINT64  Available:3;  // Available for use by system software
+UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+UINT64  AvabilableHigh:11;// Available for use by system software
+UINT64  Nx:1; // 0 = Execute Code,
+  //   1 = No Code Execution
+  } Bits;
+  UINT64Uint64;
+} PAGE_TABLE_4K_ENTRY;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+  struct {
+UINT64  Prese

[edk2-devel] [RFC PATCH 3/9] OvmfPkg/AmdSev: Setup Migration Handler Mailbox

2021-08-18 Thread Tobin Feldman-Fitzthum
The migration handler communicates with the hypervisor using a
special mailbox, a page of shared memory where pending commands
can be written. Another shared page is used to pass the incoming
or outgoing guest memory pages. These pages are set aside in MEMFD,
which this patch expands, and reserved as runtime memory in
ConfidentialMigrationPei, which this patch introduces.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/OvmfPkg.dec   |  5 +++
 OvmfPkg/AmdSev/AmdSevX64.dsc  |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf  | 12 ---
 .../ConfidentialMigrationPei.inf  | 35 +++
 .../ConfidentialMigrationPei.c| 25 +
 5 files changed, 74 insertions(+), 4 deletions(-)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index cfc645619d..1252582c99 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -331,6 +331,11 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableBase|0x0|UINT32|0x47
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize|0x0|UINT32|0x48
 
+  ## Area used by the confidential migration handler to communicate with
+  # the hypervisor.
+  
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|0x0|UINT32|0x4b
+  
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize|0x0|UINT32|0x4c
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 982ecaf70e..cd6189f330 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -623,6 +623,7 @@
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf
   OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+  OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 9bf17b8d51..a8e296e641 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -36,10 +36,10 @@ FV = SECFV
 
 [FD.MEMFD]
 BaseAddress   = $(MEMFD_BASE_ADDRESS)
-Size  = 0xD0
+Size  = 0xE0
 ErasePolarity = 1
 BlockSize = 0x1
-NumBlocks = 0xD0
+NumBlocks = 0xE0
 
 0x00|0x006000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
@@ -71,11 +71,14 @@ 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.P
 0x01|0x01
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
-0x02|0x0E
+0x02|0x003000
+gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+
+0x12|0x0E
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
 FV = PEIFV
 
-0x10|0xC0
+0x20|0xC0
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
 FV = DXEFV
 
@@ -148,6 +151,7 @@ INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
 INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
 INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+INF  OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
new file mode 100644
index 00..918cf22abd
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
@@ -0,0 +1,35 @@
+## @file
+#  PEI support for confidential migration.
+#
+#  Copyright (C) 2021 IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 0x00010005
+  BASE_NAME  = ConfidentialMigration
+  FILE_GUID  = a747792e-71a1-4c24-84a9-a76a0a279878
+  MODULE_TYPE= PEIM
+  VERSION_STRING = 1.0
+  ENTRY_POINT= InitializeConfidentialMigrationPei
+
+[Sources]
+  ConfidentialMigrationPei.c
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  HobLib
+  PeimEntryPoint
+  PcdLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c 
b/OvmfPkg/AmdSev/ConfidentialMigration

[edk2-devel] [RFC PATCH 2/9] OvmfPkg/PlatfomPei: Set Confidential Migration PCD

2021-08-18 Thread Tobin Feldman-Fitzthum
Confidential Migration relies on two boolean PCDs set from FW_CFG

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/PlatformPei/PlatformPei.inf |  2 ++
 OvmfPkg/PlatformPei/Platform.c  | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index 89d1f76368..2d92184c19 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -89,6 +89,8 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd
   gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
   gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase
+  gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+  gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
   gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index d3a20122a2..f0963aaba9 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -272,6 +272,15 @@ NoexecDxeInitialization (
   UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdSetNxForStack);
 }
 
+VOID
+ConfidentialMigrationInitialization (
+  VOID
+  )
+{
+  UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdStartConfidentialMigrationHandler);
+  UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdIsConfidentialMigrationTarget);
+}
+
 VOID
 PciExBarInitialization (
   VOID
@@ -742,6 +751,7 @@ InitializePlatform (
 
   InstallClearCacheCallback ();
   AmdSevInitialize ();
+  ConfidentialMigrationInitialization ();
   MiscInitialization ();
   InstallFeatureControlCallback ();
 
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 1/9] OvmfPkg/AmdSev: Base for Confidential Migration Handler

2021-08-18 Thread Tobin Feldman-Fitzthum
Base enablement of DXE driver that supports confidential migration.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/OvmfPkg.dec   |  5 ++
 OvmfPkg/AmdSev/AmdSevX64.dsc  |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf  |  1 +
 .../ConfidentialMigrationDxe.inf  | 34 
 .../ConfidentialMigrationDxe.c| 53 +++
 5 files changed, 94 insertions(+)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 3978852557..cfc645619d 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -370,6 +370,11 @@
   #  instance in PiSmmCpuDxeSmm, and CpuHotplugSmm.
   gUefiOvmfPkgTokenSpaceGuid.PcdCpuHotEjectDataAddress|0|UINT64|0x46
 
+  ## Set via FW_CFG to enable confidential migration as source or target.
+  #
+  
gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget|FALSE|BOOLEAN|0x49
+  
gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler|FALSE|BOOLEAN|0x4a
+
 [PcdsFeatureFlag]
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index e6cd10b759..982ecaf70e 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -790,6 +790,7 @@
 !endif
   OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
   OvmfPkg/AmdSev/Grub/Grub.inf
+  OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 !if $(BUILD_SHELL) == TRUE
   ShellPkg/Application/Shell/Shell.inf {
 
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 0a89749700..9bf17b8d51 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -274,6 +274,7 @@ INF  
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
 !endif
 INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
 INF  OvmfPkg/AmdSev/Grub/Grub.inf
+INF OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 !if $(BUILD_SHELL) == TRUE
 INF  ShellPkg/Application/Shell/Shell.inf
 !endif
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
new file mode 100644
index 00..6e3fa7e51c
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -0,0 +1,34 @@
+## @file
+#
+#  Copyright (C) 2021 IBM Corporation.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 0x00010005
+  BASE_NAME  = ConfidentialMigration
+  FILE_GUID  = 5c2978f4-f175-434b-9e6c-9b03bd7e346f
+  MODULE_TYPE= DXE_RUNTIME_DRIVER
+  VERSION_STRING = 1.0
+  ENTRY_POINT= SetupMigrationHandler
+
+[Sources]
+  ConfidentialMigrationDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
+  gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
new file mode 100644
index 00..f0dfbd279e
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -0,0 +1,53 @@
+/** @file
+  In-guest support for confidential migration
+
+  Copyright (C) 2021 IBM Coporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include 
+#include 
+
+VOID
+EFIAPI
+MigrationHandlerMain ()
+{
+  DebugPrint (DEBUG_INFO,"Migration Handler Started\n");
+
+}
+
+/**
+SetupMigrationHandler runs in the firmware of the main VM to setup
+regions of memory that the Migration Handler can use when executing
+in the mirror VM.
+
+**/
+EFI_STATUS
+EFIAPI
+SetupMigrationHandler (
+  IN EFI_HANDLE   ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+
+  if (!PcdGetBool(PcdStartConfidentialMigrationHandler)) {
+return 0;
+  }
+
+  //
+  // If VM is migration target, wait until hypervisor modifies CPU state
+  // and restarts execution.
+  //
+  if (PcdGetBool(PcdIsConfidentialMigrationTarget)) {
+DebugPrint (DEBUG_INFO,"Waiting for incoming confidential migration.\n");
+
+while (1) {
+  CpuPause ();
+}
+  }
+
+  //
+  // If VM is migration source, continue with boot.
+  //
+  return 0;
+}
-- 
2.20.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#79518): https://edk2.groups.io/g/devel/message/79518
Mute This Topic: https://groups.io/mt/84982979/21656
Group Owner: devel+

[edk2-devel] [RFC PATCH 0/9] Firmware Support for Fast Live Migration for AMD SEV

2021-08-18 Thread Tobin Feldman-Fitzthum
With AMD SEV the hypervisor cannot decrypt or move guest memory pages. 
This makes migration tricky. While the AMD Secure Processor can
export/import pages wrapped with a transport key, the bandwidth is
limited. We look to provide similar support via firmware. In particular,
we implement a Migration Handler (MH) in OVMF. The MH runs in a separate
mirror VM that shares the memory of the guest. To migrate a guest, the
HV asks the MH on the source to export wrapped pages, which the MH
on the target will import. To start the MH on the source or the target
the HV boots the mirror VM to a custom entry vector implemented in these
patches.

This RFC does not include encryption support. The pages are passed
to/from the HV in plaintext. This RFC depends on mirror VM support
already upstreamed in KVM, AMD page encryption status tracking
(Ashish Kalra's v6 OVMF live migration patches), mirror VM support in
QEMU (Ashish's v1 QEMU RFC), page encryption status tracking support in
QEMU (Ashish QEMU guest live migration support v4), and MH support in
QEMU (coming soon). This RFC is aimed at SEV only. The general design
carries over to SEV-ES and SEV-SNP, but extra support is required.

Dov Murik (1):
  OvmfPkg/AmdSev: Build page table for migration handler

Tobin Feldman-Fitzthum (8):
  OvmfPkg/AmdSev: Base for Confidential Migration Handler
  OvmfPkg/PlatfomPei: Set Confidential Migration PCD
  OvmfPkg/AmdSev: Setup Migration Handler Mailbox
  OvmfPkg/AmdSev: MH support for mailbox protocol
  OvmfPkg/AmdSev: Don't overwrite mailbox or pagetables
  OvmfPkg/AmdSev: Don't overwrite MH stack
  OvmfPkg/AmdSev: Add Migration Handler entry point
  OvmfPkg/ResetVector: Expose Migration Handler Entry Addresses

 OvmfPkg/OvmfPkg.dec   |  13 +
 OvmfPkg/AmdSev/AmdSevX64.dsc  |   2 +
 OvmfPkg/AmdSev/AmdSevX64.fdf  |  16 +-
 .../ConfidentialMigrationDxe.inf  |  38 +++
 .../ConfidentialMigrationPei.inf  |  37 +++
 OvmfPkg/PlatformPei/PlatformPei.inf   |   2 +
 OvmfPkg/ResetVector/ResetVector.inf   |   1 +
 .../ConfidentialMigration/VirtualMemory.h | 177 
 .../ConfidentialMigrationDxe.c| 272 ++
 .../ConfidentialMigrationPei.c|  31 ++
 OvmfPkg/PlatformPei/Platform.c|  10 +
 .../MigrationEntryPoint.nasm  |  51 
 OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm  |  13 +
 OvmfPkg/ResetVector/ResetVector.nasmb |   1 +
 14 files changed, 660 insertions(+), 4 deletions(-)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/MigrationEntryPoint.nasm

-- 
2.20.1



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




Re: [edk2-devel] [RFC PATCH 00/14] Firmware Support for Fast Live Migration for AMD SEV

2021-03-16 Thread Tobin Feldman-Fitzthum

On 3/12/21 9:32 PM, Yao, Jiewen wrote:


Hi
We discuss the patch internally. We do see PROs and CONs with this approach.
The advantage is that it is very simple. In-VM migration can save lots of 
effort on security context restore.
On the other hand, we feel not so comfortable to reserve a dedicate CPU to 
achieve that. Similar to the feedback in the community.

Using Hot-Plug is not a solution for Intel TDX as well. It is unsupported now.

I like the idea to diverge the migration boot mode v.s. normal boot mode in SEC 
phase.
We must be very carefully handle this migration boot mode, to avoid any 
touching on system memory.
Intel TDX Virtual Firmware skips the PEI phase directly. If we choose this 
approach, SEC-based migration is our preference.

Besides this patch, we would like to understand a full picture.
1) How the key is passed from source VM to destination?
I saw you mentions: "Key sharing is out of scope for this part of the RFC."
"This will probably be implemented via inject-launch-secret in the future"

Does that mean two PSP will sync with each other and negotiate the key, after 
the Migration Agent (MA) checks the policy?


The source and destination migration handlers will need to share a key. 
If we only relied on the PSP for migration, we could use the existing 
secure channel between the PSP and the guest owner to transfer the 
pages. Unfortunately the throughput of this approach is far too low. 
Thus, we have some migration handler running on a guest vCPU with a 
transport key shared between the source and the target.


The main mechanism for getting a key to the migration handler is 
inject-launch-secret. Here the guest owner can provide a secret to the 
PSP via a secure channel and the PSP will inject it at some guest 
physical address. You use inject-launch-secret after the launch 
measurement of the guest has been generated to inject the secret 
conditionally. One approach would be to inject the transport key 
directly in the source and the target. This is pretty simple, but might 
have a few drawbacks. The injection has to happen at boot, meaning that 
the source machine would have to be provisioned with a transport key 
before a migration happens and that all migrations from that machine 
would have to use the same transport key. One way around this would be 
to inject asymmetric keys and use them to derive the transport key.


Another approach entirely is to use the PSP to migrate just a few pages, 
which might include a secret set by the source MH that the target MH 
could use to decrypt incoming pages. Using the PSP to migrate pages 
requires some extra kernel support.


For the RFC, we just assume that there is some shared key. We have 
talked some about the various options internally.



2) How the attestation is supported?
I read the whitepaper 
https://www.amd.com/system/files/TechDocs/SEV-SNP-strengthening-vm-isolation-with-integrity-protection-and-more.pdf.
It seems SEV and SEV-ES only support attestation during launch, I don't believe 
this migration feature will impact the attestation report. Am I right?
SEV-SNP supports more flexible attestation, does it include any information 
about the new migrated content?


Brijesh already addressed most of this. In our approach the MH is baked 
into the firmware, which can be attested prior to injecting the key. In 
other words there aren't any additional steps to attest the MH and it 
does not change the functionality of any existing attestation mechanisms.


-Tobin




-Original Message-
From: devel@edk2.groups.io  On Behalf Of Yao, Jiewen
Sent: Thursday, March 4, 2021 9:49 AM
To: devel@edk2.groups.io; to...@linux.ibm.com
Cc: Dov Murik ; Tobin Feldman-Fitzthum
; James Bottomley ; Hubertus Franke
; Brijesh Singh ; Ashish Kalra
; Jon Grimm ; Tom Lendacky
; Yao, Jiewen 
Subject: Re: [edk2-devel] [RFC PATCH 00/14] Firmware Support for Fast Live
Migration for AMD SEV

Hi Tobin
Thanks for your patch.
You may that Intel is working on TDX for the same live migration feature.

Please give me some time (about 1 work week) to digest and evaluate the patch
and impact.
Then I will provide feedback.

Thank you
Yao Jiewen


-Original Message-
From: devel@edk2.groups.io  On Behalf Of Tobin
Feldman-Fitzthum
Sent: Wednesday, March 3, 2021 4:48 AM
To: devel@edk2.groups.io
Cc: Dov Murik ; Tobin Feldman-Fitzthum
; Tobin Feldman-Fitzthum ; James
Bottomley ; Hubertus Franke ;
Brijesh Singh ; Ashish Kalra

;

Jon Grimm ; Tom Lendacky

Subject: [edk2-devel] [RFC PATCH 00/14] Firmware Support for Fast Live
Migration for AMD SEV

This is a demonstration of fast migration for encrypted virtual machines
using a Migration Handler that lives in OVMF. This demo uses AMD SEV,
but the ideas may generalize to other confidential computing platforms.
With AMD SEV, guest memory is encrypted and the hypervisor cannot access
or move it. This makes migration tricky. In this demo, we show how the
HV can ask a Migration Handler 

Re: [edk2-devel] [RFC PATCH 00/14] Firmware Support for Fast Live Migration for AMD SEV

2021-03-05 Thread Tobin Feldman-Fitzthum




On Fri, Mar 05, 2021 at 10:44:23AM +, Ashish Kalra wrote:

On Wed, Mar 03, 2021 at 01:25:40PM -0500, Tobin Feldman-Fitzthum wrote:

Hi Tobin,

On 03/02/21 21:48, Tobin Feldman-Fitzthum wrote:

This is a demonstration of fast migration for encrypted virtual machines
using a Migration Handler that lives in OVMF. This demo uses AMD SEV,
but the ideas may generalize to other confidential computing platforms.
With AMD SEV, guest memory is encrypted and the hypervisor cannot access
or move it. This makes migration tricky. In this demo, we show how the
HV can ask a Migration Handler (MH) in the firmware for an encrypted
page. The MH encrypts the page with a transport key prior to releasing
it to the HV. The target machine also runs an MH that decrypts the page
once it is passed in by the target HV. These patches are not ready for
production, but the are a full end-to-end solution that facilitates a
fast live migration between two SEV VMs.

Corresponding patches for QEMU have been posted my colleague Dov Murik
on qemu-devel. Our approach needs little kernel support, requiring only
one hypercall that the guest can use to mark a page as encrypted or
shared. This series includes updated patches from Ashish Kalra and
Brijesh Singh that allow OVMF to use this hypercall.

The MH runs continuously in the guest, waiting for communication from
the HV. The HV starts an additional vCPU for the MH but does not expose
it to the guest OS via ACPI. We use the MpService to start the MH. The
MpService is only available at runtime and processes that are started by
it are usually cleaned up on ExitBootServices. Since we need the MH to
run continuously, we had to make some modifications. Ideally a feature
could be added to the MpService to allow for the starting of
long-running processes. Besides migration, this could support other
background processes that need to operate within the encryption
boundary. For now, we have included a handful of patches that modify the
MpService to allow the MH to keep running after ExitBootServices. These
are temporary.

I plan to do a lightweight review for this series. (My understanding is
that it's an RFC and not actually being proposed for merging.)

Regarding the MH's availability at runtime -- does that necessarily
require the isolation of an AP? Because in the current approach,
allowing the MP Services to survive into OS runtime (in some form or
another) seems critical, and I don't think it's going to fly.

I agree that the UefiCpuPkg patches have been well separated from the
rest of the series, but I'm somewhat doubtful the "firmware-initiated
background process" idea will be accepted. Have you investigated
exposing a new "runtime service" (a function pointer) via the UEFI
Configuration table, and calling that (perhaps periodically?) from the
guest kernel? It would be a form of polling I guess. Or maybe, poll the
mailbox directly in the kernel, and call the new firmware runtime
service when there's an actual command to process.

Continuous runtime availability for the MH is almost certainly the most
controversial part of this proposal, which is why I put it in the cover
letter and why it's good to discuss.

(You do spell out "little kernel support", and I'm not sure if that's a
technical benefit, or a political / community benefit.)

As you allude to, minimal kernel support is really one of the main things
that shapes our approach. This is partly a political and practical benefit,
but there are also technical benefits. Having the MH in firmware likely
leads to higher availability. It can be accessed when the OS is unreachable,
perhaps during boot or when the OS is hung. There are also potential
portability advantages although we do currently require support for one
hypercall. The cost of implementing this hypercall is low.

Generally speaking, our task is to find a home for functionality that was
traditionally provided by the hypervisor, but that needs to be inside the
trust domain, but that isn't really part of a guest. A meta-goal of this
project is to figure out the best way to do this.


I'm quite uncomfortable with an attempt to hide a CPU from the OS via
ACPI. The OS has other ways to learn (for example, a boot loader could
use the MP services itself, stash the information, and hand it to the OS
kernel -- this would minimally allow for detecting an inconsistency in
the OS). What about "all-but-self" IPIs too -- the kernel might think
all the processors it's poking like that were under its control.

This might be the second most controversial piece. Here's a question: if we
could successfully hide the MH vCPU from the OS, would it still make you
uncomfortable? In other words, is the worry that there might be some
inconsistency or more generally that there is something hidden from the OS?
One thing to think about is that the guest owner should generally be aware
that there is a migration handler running. The way I see it, a guest owner
of an 

Re: [edk2-devel] [RFC PATCH 00/14] Firmware Support for Fast Live Migration for AMD SEV

2021-03-03 Thread Tobin Feldman-Fitzthum




Hi Tobin,

On 03/02/21 21:48, Tobin Feldman-Fitzthum wrote:

This is a demonstration of fast migration for encrypted virtual machines
using a Migration Handler that lives in OVMF. This demo uses AMD SEV,
but the ideas may generalize to other confidential computing platforms.
With AMD SEV, guest memory is encrypted and the hypervisor cannot access
or move it. This makes migration tricky. In this demo, we show how the
HV can ask a Migration Handler (MH) in the firmware for an encrypted
page. The MH encrypts the page with a transport key prior to releasing
it to the HV. The target machine also runs an MH that decrypts the page
once it is passed in by the target HV. These patches are not ready for
production, but the are a full end-to-end solution that facilitates a
fast live migration between two SEV VMs.

Corresponding patches for QEMU have been posted my colleague Dov Murik
on qemu-devel. Our approach needs little kernel support, requiring only
one hypercall that the guest can use to mark a page as encrypted or
shared. This series includes updated patches from Ashish Kalra and
Brijesh Singh that allow OVMF to use this hypercall.

The MH runs continuously in the guest, waiting for communication from
the HV. The HV starts an additional vCPU for the MH but does not expose
it to the guest OS via ACPI. We use the MpService to start the MH. The
MpService is only available at runtime and processes that are started by
it are usually cleaned up on ExitBootServices. Since we need the MH to
run continuously, we had to make some modifications. Ideally a feature
could be added to the MpService to allow for the starting of
long-running processes. Besides migration, this could support other
background processes that need to operate within the encryption
boundary. For now, we have included a handful of patches that modify the
MpService to allow the MH to keep running after ExitBootServices. These
are temporary.

I plan to do a lightweight review for this series. (My understanding is
that it's an RFC and not actually being proposed for merging.)

Regarding the MH's availability at runtime -- does that necessarily
require the isolation of an AP? Because in the current approach,
allowing the MP Services to survive into OS runtime (in some form or
another) seems critical, and I don't think it's going to fly.

I agree that the UefiCpuPkg patches have been well separated from the
rest of the series, but I'm somewhat doubtful the "firmware-initiated
background process" idea will be accepted. Have you investigated
exposing a new "runtime service" (a function pointer) via the UEFI
Configuration table, and calling that (perhaps periodically?) from the
guest kernel? It would be a form of polling I guess. Or maybe, poll the
mailbox directly in the kernel, and call the new firmware runtime
service when there's an actual command to process.
Continuous runtime availability for the MH is almost certainly the most 
controversial part of this proposal, which is why I put it in the cover 
letter and why it's good to discuss.

(You do spell out "little kernel support", and I'm not sure if that's a
technical benefit, or a political / community benefit.)


As you allude to, minimal kernel support is really one of the main 
things that shapes our approach. This is partly a political and 
practical benefit, but there are also technical benefits. Having the MH 
in firmware likely leads to higher availability. It can be accessed when 
the OS is unreachable, perhaps during boot or when the OS is hung. There 
are also potential portability advantages although we do currently 
require support for one hypercall. The cost of implementing this 
hypercall is low.


Generally speaking, our task is to find a home for functionality that 
was traditionally provided by the hypervisor, but that needs to be 
inside the trust domain, but that isn't really part of a guest. A 
meta-goal of this project is to figure out the best way to do this.




I'm quite uncomfortable with an attempt to hide a CPU from the OS via
ACPI. The OS has other ways to learn (for example, a boot loader could
use the MP services itself, stash the information, and hand it to the OS
kernel -- this would minimally allow for detecting an inconsistency in
the OS). What about "all-but-self" IPIs too -- the kernel might think
all the processors it's poking like that were under its control.


This might be the second most controversial piece. Here's a question: if 
we could successfully hide the MH vCPU from the OS, would it still make 
you uncomfortable? In other words, is the worry that there might be some 
inconsistency or more generally that there is something hidden from the 
OS? One thing to think about is that the guest owner should generally be 
aware that there is a migration handler running. The way I see it, a 
guest owner of an SEV VM would need to opt-in to migration and should 
then expect that there is an MH running even if they a

Re: [edk2-devel] [RFC PATCH 03/14] OvmfPkg/PlatformDxe: Add support for SEV live migration.

2021-03-03 Thread Tobin Feldman-Fitzthum



On 3/3/21 11:41 AM, Ashish Kalra wrote:

Hello Tobin,

You don't need this patch for MH support, this patch is only required
for (SEV) slow migration support.


If the SevLiveMigrationEnabled variable is not set, the bitmap sync does 
not work correctly (bitmap all zeros), at least for the version of the 
kernel we have been using. Since the bitmap will be replaced, this might 
not be necessary in the future but it is for our setup at the moment.


-Tobin



Thanks,
Ashish

On Tue, Mar 02, 2021 at 03:48:28PM -0500, Tobin Feldman-Fitzthum wrote:

From: Ashish Kalra 

Detect for KVM hypervisor and check for SEV live migration
feature support via KVM_FEATURE_CPUID, if detected setup a new
UEFI enviroment variable to indicate OVMF support for SEV
live migration.

Signed-off-by: Ashish Kalra 
---
  OvmfPkg/OvmfPkg.dec  |  1 +
  OvmfPkg/PlatformDxe/Platform.inf |  2 +
  OvmfPkg/Include/Guid/MemEncryptLib.h | 16 +
  OvmfPkg/PlatformDxe/PlatformConfig.h |  5 ++
  OvmfPkg/PlatformDxe/AmdSev.c | 99 
  OvmfPkg/PlatformDxe/Platform.c   |  6 ++
  6 files changed, 129 insertions(+)
  create mode 100644 OvmfPkg/Include/Guid/MemEncryptLib.h
  create mode 100644 OvmfPkg/PlatformDxe/AmdSev.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4348bb45c6..4450d78b91 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -122,6 +122,7 @@
gQemuKernelLoaderFsMediaGuid  = {0x1428f772, 0xb64a, 0x441e, {0xb8, 
0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
gGrubFileGuid = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 
0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
gConfidentialComputingSecretGuid  = {0xadf956ad, 0xe98c, 0x484c, {0xae, 
0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
+  gMemEncryptGuid   = {0x0cf29b71, 0x9e51, 0x433a, {0xa3, 
0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
  
  [Ppis]

# PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/PlatformDxe/Platform.inf b/OvmfPkg/PlatformDxe/Platform.inf
index 14727c1220..2896f0a1d1 100644
--- a/OvmfPkg/PlatformDxe/Platform.inf
+++ b/OvmfPkg/PlatformDxe/Platform.inf
@@ -24,6 +24,7 @@
PlatformConfig.c
PlatformConfig.h
PlatformForms.vfr
+  AmdSev.c
  
  [Packages]

MdePkg/MdePkg.dec
@@ -56,6 +57,7 @@
  [Guids]
gEfiIfrTianoGuid
gOvmfPlatformConfigGuid
+  gMemEncryptGuid
  
  [Depex]

gEfiHiiConfigRoutingProtocolGuid  AND
diff --git a/OvmfPkg/Include/Guid/MemEncryptLib.h 
b/OvmfPkg/Include/Guid/MemEncryptLib.h
new file mode 100644
index 00..8264a647af
--- /dev/null
+++ b/OvmfPkg/Include/Guid/MemEncryptLib.h
@@ -0,0 +1,16 @@
+/** @file
+  AMD Memory Encryption GUID, define a new GUID for defining
+  new UEFI enviroment variables assocaiated with SEV Memory Encryption.
+  Copyright (c) 2020, AMD Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __MEMENCRYPT_LIB_H__
+#define __MEMENCRYPT_LIB_H__
+
+#define MEMENCRYPT_GUID \
+{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
+
+extern EFI_GUID gMemEncryptGuid;
+
+#endif
diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.h 
b/OvmfPkg/PlatformDxe/PlatformConfig.h
index 716514da21..4f662aafa4 100644
--- a/OvmfPkg/PlatformDxe/PlatformConfig.h
+++ b/OvmfPkg/PlatformDxe/PlatformConfig.h
@@ -44,6 +44,11 @@ PlatformConfigLoad (
OUT UINT64  *OptionalElements
);
  
+VOID

+AmdSevSetConfig(
+  VOID
+  );
+
  //
  // Feature flags for OptionalElements.
  //
diff --git a/OvmfPkg/PlatformDxe/AmdSev.c b/OvmfPkg/PlatformDxe/AmdSev.c
new file mode 100644
index 00..1f804984b7
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/AmdSev.c
@@ -0,0 +1,99 @@
+/**@file
+  Detect KVM hypervisor support for SEV live migration and if
+  detected, setup a new UEFI enviroment variable indicating
+  OVMF support for SEV live migration.
+  Copyright (c) 2020, Advanced Micro Devices. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+//
+// The package level header files this module uses
+//
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+  Figures out if we are running inside KVM HVM and
+  KVM HVM supports SEV Live Migration feature.
+  @retval TRUE   KVM was detected and Live Migration supported
+  @retval FALSE  KVM was not detected or Live Migration not supported
+**/
+BOOLEAN
+KvmDetectSevLiveMigrationFeature(
+  VOID
+  )
+{
+  UINT8 Signature[13];
+  UINT32 mKvmLeaf = 0;
+  UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+  Signature[12] = '\0';
+  for (mKvmLeaf = 0x4000; mKvmLeaf < 0x4001; mKvmLeaf += 0x100) {
+AsmCpuid (mKvmLeaf,
+  NULL,
+  (UINT32 *) [0],
+  (UINT32 *) [4],
+  (UINT32 *) [8]);
+
+if (!AsciiStrCmp ((CHAR8 *) Signature, "KVMKVMKVM\0\0\0")) {
+   DEBUG ((
+DEBUG_ERROR,
+"%a: KVM Detected, signature = %s\n",
+__FUN

Re: [edk2-devel] [RFC PATCH 02/14] OvmfPkg/PlatformPei: Mark SEC GHCB page in the page encrpytion bitmap.

2021-03-03 Thread Tobin Feldman-Fitzthum




Hello Tobin,

Just a high level question, why is this patch included in this
patch series, i don't think you are supporting SEV-ES platform
migration in this patch-set ?


You are correct that we don't support migration for SEV-ES machines, 
although our approach can potentially be adapted for SEV-ES. I was on 
the fence about including this patch, because we don't strictly need it 
for migration. I'm not sure if the SEC GHCB would be significant even if 
we did support SEV-ES migration. Ultimately it seemed like a good idea 
because the SEV firmware build does otherwise support SEV-ES. Since I 
was introducing the hypercall in an environment where SEV-ES can be 
enabled, it seemed reasonable to include. Syncing page encryption status 
hypothetically has uses beyond migration.


Note that I am not adding full support for the hypercall in OVMF, which 
might be a good idea at some point.


-Tobin


Thanks,
Ashish

On Tue, Mar 02, 2021 at 03:48:27PM -0500, Tobin Feldman-Fitzthum wrote:

From: Ashish Kalra 

Mark the SEC GHCB page that is mapped as unencrypted in
ResetVector code in the hypervisor page encryption bitmap.

Cc: Jordan Justen 
Cc: Laszlo Ersek 
Cc: Ard Biesheuvel 

Signed-off-by: Ashish Kalra 
---
  OvmfPkg/PlatformPei/AmdSev.c | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index dddffdebda..c72eeb37c5 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -15,6 +15,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -52,6 +53,15 @@ AmdSevEsInitialize (
PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
ASSERT_RETURN_ERROR (PcdStatus);
  
+  //

+  // GHCB_BASE setup during reset-vector needs to be marked as
+  // decrypted in the hypervisor page encryption bitmap.
+  //
+  SetMemoryEncDecHypercall3 (FixedPcdGet32 (PcdOvmfSecGhcbBase),
+EFI_SIZE_TO_PAGES(FixedPcdGet32 (PcdOvmfSecGhcbSize)),
+FALSE
+);
+
//
// Allocate GHCB and per-CPU variable pages.
//   Since the pages must survive across the UEFI to OS transition
--
2.20.1









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




[edk2-devel] [RFC PATCH 07/14] OvmfPkg/AmdSev: MH support for mailbox protocol

2021-03-02 Thread Tobin Feldman-Fitzthum
The migration handler communicates with the hypervisor
via a shared mailbox page. The MH can perform four functions
at the behest of the HV: init, save page, restore page, and
reset.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.inf  |  1 +
 .../ConfidentialMigrationDxe.c| 78 +++
 2 files changed, 79 insertions(+)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index a4906a2451..49457d5d17 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -34,6 +34,7 @@
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
   gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
 
 [Depex]
   gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 6d9fe7043b..8402fcc4fa 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -9,16 +9,94 @@
 #include 
 #include 
 #include 
+#include 
 
+//
+// Functions implemented by the migration handler
+//
+#define MH_FUNC_INIT  0
+#define MH_FUNC_SAVE_PAGE 1
+#define MH_FUNC_RESTORE_PAGE  2
+#define MH_FUNC_RESET 3
+
+//
+// Return codes for MH functions
+//
+#define MH_SUCCESS0
+#define MH_INVALID_FUNC (-1)
+#define MH_AUTH_ERR (-2)
+
+//
+// Index of CPU that MH runs on.
+//
 UINTN MigrationHandlerCpuIndex;
 
+//
+// Mailbox for communication with hypervisor
+//
+typedef volatile struct {
+  UINT64   nr;
+  UINT64   gpa;
+  UINT32   do_prefetch;
+  UINT32   ret;
+  UINT32   go;
+  UINT32   done;
+} MH_COMMAND_PARAMETERS;
+
+
 VOID
 EFIAPI
 MigrationHandlerMain (
   IN OUT VOID *Buffer
   )
 {
+  UINT64   params_base;
+  MH_COMMAND_PARAMETERS*params;
+  VOID *page_va;
+
   DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");
+
+  params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase);
+  params = (VOID *)params_base;
+  page_va = (VOID *)params_base + 0x1000;
+
+  DisableInterrupts();
+  params->go = 0;
+
+  while (1) {
+while (!params->go) {
+  CpuPause();
+}
+params->done = 0;
+
+switch (params->nr) {
+case MH_FUNC_INIT:
+  params->ret = MH_SUCCESS;
+  break;
+
+case MH_FUNC_SAVE_PAGE:
+  CopyMem(page_va, (VOID *)params->gpa, 4096);
+  params->ret = MH_SUCCESS;
+  break;
+
+case MH_FUNC_RESTORE_PAGE:
+  CopyMem((VOID *)params->gpa, page_va, 4096);
+  params->ret = MH_SUCCESS;
+  break;
+
+case MH_FUNC_RESET:
+  params->ret = MH_SUCCESS;
+  break;
+
+default:
+  params->ret = MH_INVALID_FUNC;
+  break;
+}
+
+params->go = 0;
+params->done = 1;
+
+  }
 }
 
 EFI_STATUS
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 14/14] OvmfPkg/AmdSev: MH page encryption POC

2021-03-02 Thread Tobin Feldman-Fitzthum
This code is for demonstration purposes only. It is not secure or
robust. The purpose is to show where encryption will be incorporated
and to get a sense of the performance impact of adding encryption.

We plan to use AES-GCM to encrypt the pages as a stream. This will
also allow us to verify the GPA as part of the AAD, ensuring that
a malicious hypervisor hasn't exchanged pages in-flight.

Currently the CryptoPkg and the BaseCryptLib do not expose AES-GCM,
despite it being included in OpensslLib. Thus, we use CBC here.

Key sharing is out of scope for this part of the RFC. We assume that
the source and destination MH share a key. This will probably be
implemented via inject-launch-secret in the future. For now, we
hardcode a key, but this is strictly temporary.

We have had trouble using RandomBytes() in the MH when SEV is
enabled. Thus the IV is hardcoded. Again, this is temporary.

The HV and the MH will exchange information pertaining to encryption,
like the IV, via an additional header on the shared mailbox page.

This patch does not do any safety checks or handle encrypt/decrypt
failures. Again, this is only here to show where encryption will
go and generally how the MH on the source and target can share
pages without exposing guest memory to the HV.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.inf  |  2 ++
 .../ConfidentialMigrationDxe.c| 36 +--
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 2816952863..ae074a8b07 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -22,6 +22,7 @@
   MdePkg/MdePkg.dec
   OvmfPkg/OvmfPkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
+  CryptoPkg/CryptoPkg.dec
 
 [LibraryClasses]
   MemoryAllocationLib
@@ -29,6 +30,7 @@
   UefiBootServicesTableLib
   MpInitLib
   UefiDriverEntryPoint
+  BaseCryptLib
 
 [Protocols]
   gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 42b99be552..a9cb490561 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "VirtualMemory.h"
 #include "MpLib.h"
@@ -46,6 +47,14 @@ typedef volatile struct {
   UINT32   done;
 } MH_COMMAND_PARAMETERS;
 
+//
+// Additional header for encryption support.
+//
+struct page_hdr {
+  UINT8IV[16];
+  UINT8tag[16];
+};
+
 //
 // Addresses for MH page table.
 //
@@ -57,6 +66,20 @@ STATIC PHYSICAL_ADDRESS  mMigrationHelperPageTables = 0;
 //
 #define UNENC_VIRT_ADDR_BASE0xff80ULL
 
+//
+// Key shared between source and target MH (temporary)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 cipher_key[] = {
+  0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 
0x20, 0x25, 0xa4, 0x5a
+ };
+
+//
+// IV for CBC cipher (temporary). We are having trouble with
+// calling RandomBytes from inside the Migration Handler
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 Ivec[] = {
+  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
+};
 
 /**
   Allocates and fills in custom page tables for Migration Handler.
@@ -159,6 +182,8 @@ MigrationHandlerMain (
   UINT64   params_base;
   MH_COMMAND_PARAMETERS*params;
   VOID *page_va;
+  VOID *cipher_ctx;
+  INTN ctx_size;
 
   DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");
 
@@ -171,6 +196,7 @@ MigrationHandlerMain (
   params_base = mailbox_start + UNENC_VIRT_ADDR_BASE;
   params = (VOID *)params_base;
   page_va = (VOID *)params_base + 0x1000;
+  //struct page_hdr *hdr_va = (void *) params_base + 0x800;
 
   mailbox_end = mailbox_start + 2 * EFI_PAGE_SIZE;
 
@@ -180,6 +206,9 @@ MigrationHandlerMain (
   stack_end = GetMHTopOfStack();
   stack_start = stack_end - PcdGet32(PcdCpuApStackSize);
 
+  ctx_size = AesGetContextSize ();
+  cipher_ctx = AllocateRuntimePool (ctx_size);
+
   DisableInterrupts();
   params->go = 0;
 
@@ -195,7 +224,9 @@ MigrationHandlerMain (
   break;
 
 case MH_FUNC_SAVE_PAGE:
-  CopyMem(page_va, (VOID *)params->gpa, 4096);
+  AesInit (cipher_ctx, cipher_key, 128);
+  AesCbcEncrypt(cipher_ctx, (VOID *)params->gpa, 4096, Ivec, page_va);
+
   params->ret = MH_SUCCESS;
   break;
 
@@ -208,7 +239,8 @@ MigrationHandlerMain (
   (params->gpa >= stack_start && params->gpa < stack_end)) {
   }
   else {
-CopyMem((VOID *)params->gpa, page_va, 4096);
+AesInit (cipher_ctx, cipher_key, 128

[edk2-devel] [RFC PATCH 13/14] OvmfPkg/AmdSev: Don't overwrite MH stack

2021-03-02 Thread Tobin Feldman-Fitzthum
When restoring pages, the Migration Handler shoudl avoid overwriting
its own stack.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.inf  |   2 +
 OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h  | 235 ++
 .../ConfidentialMigrationDxe.c|  30 ++-
 3 files changed, 266 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 8dadfd1d13..2816952863 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -16,6 +16,7 @@
 [Sources]
   ConfidentialMigrationDxe.c
   VirtualMemory.h
+  MpLib.h
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -36,6 +37,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
   gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
   gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
 
 [Depex]
   gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h 
b/OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h
new file mode 100644
index 00..5007e25243
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h
@@ -0,0 +1,235 @@
+/** @file
+  Common header file for MP Initialize Library.
+  -- adapted from UefiCpuPkg/Library/MpInitLib/MpLib.h
+  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+  Copyright (c) 2020, AMD Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MP_LIB_H_
+#define _MP_LIB_H_
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CPU_INIT_MP_LIB_HOB_GUID \
+  { \
+0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 
0x4a } \
+  }
+
+
+//
+// CPU exchange information for switch BSP
+//
+typedef struct {
+  UINT8 State;// offset 0
+  UINTN StackPointer; // offset 4 / 8
+  IA32_DESCRIPTOR   Gdtr; // offset 8 / 16
+  IA32_DESCRIPTOR   Idtr; // offset 14 / 26
+} CPU_EXCHANGE_ROLE_INFO;
+
+//
+// AP initialization state during APs wakeup
+//
+typedef enum {
+  ApInitConfig   = 1,
+  ApInitReconfig = 2,
+  ApInitDone = 3
+} AP_INIT_STATE;
+
+//
+// AP state
+//
+// The state transitions for an AP when it process a procedure are:
+//  Idle > Ready > Busy > Idle
+//   [BSP]   [AP]   [AP]
+//
+typedef enum {
+  CpuStateIdle,
+  CpuStateReady,
+  CpuStateBusy,
+  CpuStateFinished,
+  CpuStateDisabled
+} CPU_STATE;
+
+//
+// CPU volatile registers around INIT-SIPI-SIPI
+//
+typedef struct {
+  UINTN  Cr0;
+  UINTN  Cr3;
+  UINTN  Cr4;
+  UINTN  Dr0;
+  UINTN  Dr1;
+  UINTN  Dr2;
+  UINTN  Dr3;
+  UINTN  Dr6;
+  UINTN  Dr7;
+  IA32_DESCRIPTORGdtr;
+  IA32_DESCRIPTORIdtr;
+  UINT16 Tr;
+} CPU_VOLATILE_REGISTERS;
+
+//
+// AP related data
+//
+typedef struct {
+  SPIN_LOCK  ApLock;
+  volatile UINT32*StartupApSignal;
+  volatile UINTN ApFunction;
+  volatile UINTN ApFunctionArgument;
+  BOOLEANCpuHealthy;
+  volatile CPU_STATE State;
+  CPU_VOLATILE_REGISTERS VolatileRegisters;
+  BOOLEANWaiting;
+  BOOLEAN*Finished;
+  UINT64 ExpectedTime;
+  UINT64 CurrentTime;
+  UINT64 TotalTime;
+  EFI_EVENT  WaitEvent;
+  UINT32 ProcessorSignature;
+  UINT8  PlatformId;
+  UINT64 MicrocodeEntryAddr;
+} CPU_AP_DATA;
+
+//
+// Basic CPU information saved in Guided HOB.
+// Because the contents will be shard between PEI and DXE,
+// we need to make sure the each fields offset same in different
+// architecture.
+//
+#pragma pack (1)
+typedef struct {
+  UINT32 InitialApicId;
+  UINT32 ApicId;
+  UINT32 Health;
+  UINT64 ApTopOfStack;
+} CPU_INFO_IN_HOB;
+#pragma pack ()
+
+//
+// AP reset code information including code address and size,
+// this structure will be shared be C code and assembly code.
+// It is natural aligned by design.
+//
+typedef struct {
+  UINT8 *RendezvousFunnelAddress;
+  UINTN ModeEntryOffset;
+  UINTN RendezvousFunnelSize;
+  UINT8 *RelocateApLoopFuncAddress;

[edk2-devel] [RFC PATCH 11/14] OvmfPkg/AmdSev: Build page table for migration handler

2021-03-02 Thread Tobin Feldman-Fitzthum
From: Dov Murik 

The migration handler builds its own page tables and switches
to them. The MH pagetables are reserved as runtime memory.

When the hypervisor asks the MH to import/export a page, the HV
writes the guest physical address of the page in question to the
mailbox. The MH uses an identity mapping so that it can read/write
whatever GPA is requested by the HV. The hypervisor only asks the
MH to import/export encrypted pages. Thus, the C-Bit can be set
for every page in the identity map.

The MH also needs to read shared pages, such as the mailbox.
These are mapped at an offset. The offset must be added to
the physical address before it can be resolved.

Signed-off-by: Tobin Feldman-Fitzthum 
Signed-off-by: Dov Murik 
---
 .../ConfidentialMigrationDxe.inf  |   1 +
 .../ConfidentialMigration/VirtualMemory.h | 177 ++
 .../ConfidentialMigrationDxe.c|  88 -
 3 files changed, 265 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
index 49457d5d17..8dadfd1d13 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -15,6 +15,7 @@
 
 [Sources]
   ConfidentialMigrationDxe.c
+  VirtualMemory.h
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h 
b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
new file mode 100644
index 00..c50cb64c63
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
@@ -0,0 +1,177 @@
+/** @file
+  Virtual Memory Management Services to set or clear the memory encryption bit
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+  Copyright (c) 2017, AMD Incorporated. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+  Code is derived from OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h
+
+**/
+
+#ifndef __VIRTUAL_MEMORY__
+#define __VIRTUAL_MEMORY__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SYS_CODE64_SEL 0x38
+
+#pragma pack(1)
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+typedef union {
+  struct {
+UINT64  Present:1;// 0 = Not present in memory,
+  //   1 = Present in memory
+UINT64  ReadWrite:1;  // 0 = Read-Only, 1= Read/Write
+UINT64  UserSupervisor:1; // 0 = Supervisor, 1=User
+UINT64  WriteThrough:1;   // 0 = Write-Back caching,
+  //   1 = Write-Through caching
+UINT64  CacheDisabled:1;  // 0 = Cached, 1=Non-Cached
+UINT64  Accessed:1;   // 0 = Not accessed,
+  //   1 = Accessed (set by CPU)
+UINT64  Reserved:1;   // Reserved
+UINT64  MustBeZero:2; // Must Be Zero
+UINT64  Available:3;  // Available for use by system software
+UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+UINT64  AvabilableHigh:11;// Available for use by system software
+UINT64  Nx:1; // No Execute bit
+  } Bits;
+  UINT64Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 4KB
+//
+typedef union {
+  struct {
+UINT64  Present:1;// 0 = Not present in memory,
+  //   1 = Present in memory
+UINT64  ReadWrite:1;  // 0 = Read-Only, 1= Read/Write
+UINT64  UserSupervisor:1; // 0 = Supervisor, 1=User
+UINT64  WriteThrough:1;   // 0 = Write-Back caching,
+  //   1 = Write-Through caching
+UINT64  CacheDisabled:1;  // 0 = Cached, 1=Non-Cached
+UINT64  Accessed:1;   // 0 = Not accessed,
+  //   1 = Accessed (set by CPU)
+UINT64  Dirty:1;  // 0 = Not Dirty, 1 = written by
+  //   processor on access to page
+UINT64  PAT:1;//
+UINT64  Global:1; // 0 = Not global page, 1 = global page
+  //   TLB not cleared on CR3 write
+UINT64  Available:3;  // Available for use by system software
+UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+UINT64  AvabilableHigh:11;// Available for use by system software
+UINT64  Nx:1; // 0 = Execute Code,
+  //   1 = No Code Execution
+  } Bits;
+  UINT64Uint64;
+} PAGE_TABLE_4K_ENTRY;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+  struct {
+UINT64  Prese

[edk2-devel] [RFC PATCH 10/14] UefiCpuPkg/CpuExceptionHandlerLib: Exception handling as runtime memory

2021-03-02 Thread Tobin Feldman-Fitzthum
Reserve IDT and other exception-related memory as runtime so
it won't be overwritten by the OS while the MH is running.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
index fd59f09ecd..35610f8cf5 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
@@ -102,7 +102,7 @@ InitializeCpuInterruptHandlers (
   EFI_CPU_INTERRUPT_HANDLER  *ExternalInterruptHandler;
 
   Status = gBS->AllocatePool (
-  EfiBootServicesCode,
+  EfiRuntimeServicesCode,
   sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM,
   (VOID **)
   );
@@ -116,7 +116,7 @@ InitializeCpuInterruptHandlers (
 }
   }
 
-  ExternalInterruptHandler = AllocateZeroPool (sizeof 
(EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
+  ExternalInterruptHandler = AllocateRuntimeZeroPool (sizeof 
(EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
   ASSERT (ExternalInterruptHandler != NULL);
 
   //
@@ -130,7 +130,7 @@ InitializeCpuInterruptHandlers (
   //
   // Create Interrupt Descriptor Table and Copy the old IDT table in
   //
-  IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 
CPU_INTERRUPT_NUM);
+  IdtTable = AllocateRuntimeZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 
CPU_INTERRUPT_NUM);
   ASSERT (IdtTable != NULL);
   CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof 
(IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);
 
@@ -138,7 +138,7 @@ InitializeCpuInterruptHandlers (
   ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);
 
   Status = gBS->AllocatePool (
-  EfiBootServicesCode,
+  EfiRuntimeServicesCode,
   TemplateMap.ExceptionStubHeaderSize * CPU_INTERRUPT_NUM,
   (VOID **)
   );
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 03/14] OvmfPkg/PlatformDxe: Add support for SEV live migration.

2021-03-02 Thread Tobin Feldman-Fitzthum
From: Ashish Kalra 

Detect for KVM hypervisor and check for SEV live migration
feature support via KVM_FEATURE_CPUID, if detected setup a new
UEFI enviroment variable to indicate OVMF support for SEV
live migration.

Signed-off-by: Ashish Kalra 
---
 OvmfPkg/OvmfPkg.dec  |  1 +
 OvmfPkg/PlatformDxe/Platform.inf |  2 +
 OvmfPkg/Include/Guid/MemEncryptLib.h | 16 +
 OvmfPkg/PlatformDxe/PlatformConfig.h |  5 ++
 OvmfPkg/PlatformDxe/AmdSev.c | 99 
 OvmfPkg/PlatformDxe/Platform.c   |  6 ++
 6 files changed, 129 insertions(+)
 create mode 100644 OvmfPkg/Include/Guid/MemEncryptLib.h
 create mode 100644 OvmfPkg/PlatformDxe/AmdSev.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4348bb45c6..4450d78b91 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -122,6 +122,7 @@
   gQemuKernelLoaderFsMediaGuid  = {0x1428f772, 0xb64a, 0x441e, {0xb8, 
0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
   gGrubFileGuid = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 
0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
   gConfidentialComputingSecretGuid  = {0xadf956ad, 0xe98c, 0x484c, {0xae, 
0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
+  gMemEncryptGuid   = {0x0cf29b71, 0x9e51, 0x433a, {0xa3, 
0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/PlatformDxe/Platform.inf b/OvmfPkg/PlatformDxe/Platform.inf
index 14727c1220..2896f0a1d1 100644
--- a/OvmfPkg/PlatformDxe/Platform.inf
+++ b/OvmfPkg/PlatformDxe/Platform.inf
@@ -24,6 +24,7 @@
   PlatformConfig.c
   PlatformConfig.h
   PlatformForms.vfr
+  AmdSev.c
 
 [Packages]
   MdePkg/MdePkg.dec
@@ -56,6 +57,7 @@
 [Guids]
   gEfiIfrTianoGuid
   gOvmfPlatformConfigGuid
+  gMemEncryptGuid
 
 [Depex]
   gEfiHiiConfigRoutingProtocolGuid  AND
diff --git a/OvmfPkg/Include/Guid/MemEncryptLib.h 
b/OvmfPkg/Include/Guid/MemEncryptLib.h
new file mode 100644
index 00..8264a647af
--- /dev/null
+++ b/OvmfPkg/Include/Guid/MemEncryptLib.h
@@ -0,0 +1,16 @@
+/** @file
+  AMD Memory Encryption GUID, define a new GUID for defining
+  new UEFI enviroment variables assocaiated with SEV Memory Encryption.
+  Copyright (c) 2020, AMD Inc. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __MEMENCRYPT_LIB_H__
+#define __MEMENCRYPT_LIB_H__
+
+#define MEMENCRYPT_GUID \
+{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
+
+extern EFI_GUID gMemEncryptGuid;
+
+#endif
diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.h 
b/OvmfPkg/PlatformDxe/PlatformConfig.h
index 716514da21..4f662aafa4 100644
--- a/OvmfPkg/PlatformDxe/PlatformConfig.h
+++ b/OvmfPkg/PlatformDxe/PlatformConfig.h
@@ -44,6 +44,11 @@ PlatformConfigLoad (
   OUT UINT64  *OptionalElements
   );
 
+VOID
+AmdSevSetConfig(
+  VOID
+  );
+
 //
 // Feature flags for OptionalElements.
 //
diff --git a/OvmfPkg/PlatformDxe/AmdSev.c b/OvmfPkg/PlatformDxe/AmdSev.c
new file mode 100644
index 00..1f804984b7
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/AmdSev.c
@@ -0,0 +1,99 @@
+/**@file
+  Detect KVM hypervisor support for SEV live migration and if
+  detected, setup a new UEFI enviroment variable indicating
+  OVMF support for SEV live migration.
+  Copyright (c) 2020, Advanced Micro Devices. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+//
+// The package level header files this module uses
+//
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+  Figures out if we are running inside KVM HVM and
+  KVM HVM supports SEV Live Migration feature.
+  @retval TRUE   KVM was detected and Live Migration supported
+  @retval FALSE  KVM was not detected or Live Migration not supported
+**/
+BOOLEAN
+KvmDetectSevLiveMigrationFeature(
+  VOID
+  )
+{
+  UINT8 Signature[13];
+  UINT32 mKvmLeaf = 0;
+  UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+  Signature[12] = '\0';
+  for (mKvmLeaf = 0x4000; mKvmLeaf < 0x4001; mKvmLeaf += 0x100) {
+AsmCpuid (mKvmLeaf,
+  NULL,
+  (UINT32 *) [0],
+  (UINT32 *) [4],
+  (UINT32 *) [8]);
+
+if (!AsciiStrCmp ((CHAR8 *) Signature, "KVMKVMKVM\0\0\0")) {
+   DEBUG ((
+DEBUG_ERROR,
+"%a: KVM Detected, signature = %s\n",
+__FUNCTION__,
+Signature
+));
+
+RegEax = 0x4001;
+RegEcx = 0;
+  AsmCpuid (0x4001, , , , );
+  if (RegEax & (1 << 14)) {
+ DEBUG ((
+DEBUG_ERROR,
+"%a: Live Migration feature supported\n",
+__FUNCTION__
+));
+return TRUE;
+ }
+}
+  }
+
+  return FALSE;
+}
+
+/**
+  Function checks if SEV Live Migration support is available, if present then 
it sets
+  a UEFI enviroment variable to be queried later using Runtime services.
+  **/
+VOID
+AmdSevSetConfig(
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  BOOLEAN SevLiveMigrationEnabled;
+
+  

[edk2-devel] [RFC PATCH 01/14] OvmfPkg/BaseMemEncryptLib: Support to issue unencrypted hypercall

2021-03-02 Thread Tobin Feldman-Fitzthum
From: Brijesh Singh 

By default all the SEV guest memory regions are considered encrypted,
if a guest changes the encryption attribute of the page (e.g mark a
page as decrypted) then notify hypervisor. Hypervisor will need to
track the unencrypted pages. The information will be used during
guest live migration, guest page migration and guest debugging.

Invoke hypercall via the new hypercall library.

This hypercall is used to notify hypervisor when a page is marked as
'decrypted' (i.e C-bit removed).

Cc: Jordan Justen 
Cc: Laszlo Ersek 
Cc: Ard Biesheuvel 

Signed-off-by: Brijesh Singh 
Signed-off-by: Ashish Kalra 
---
 .../DxeMemEncryptSevLib.inf|  1 +
 .../PeiMemEncryptSevLib.inf|  1 +
 .../X64/PeiDxeVirtualMemory.c  | 18 ++
 3 files changed, 20 insertions(+)

diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
index f2e162d680..aefcd7c0f7 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
@@ -49,6 +49,7 @@
   DebugLib
   MemoryAllocationLib
   PcdLib
+  MemEncryptHypercallLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf 
b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
index 03a78c32df..7503f56a0b 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
@@ -49,6 +49,7 @@
   DebugLib
   MemoryAllocationLib
   PcdLib
+  MemEncryptHypercallLib
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c 
b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
index d3455e812b..98a1d2e3a8 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "VirtualMemory.h"
 
@@ -585,6 +586,9 @@ SetMemoryEncDec (
   UINT64 AddressEncMask;
   BOOLEANIsWpEnabled;
   RETURN_STATUS  Status;
+  UINTN  Size;
+  BOOLEANCBitChanged;
+  PHYSICAL_ADDRESS   OrigPhysicalAddress;
 
   //
   // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings.
@@ -636,6 +640,10 @@ SetMemoryEncDec (
 
   Status = EFI_SUCCESS;
 
+  Size = Length;
+  CBitChanged = FALSE;
+  OrigPhysicalAddress = PhysicalAddress;
+
   while (Length != 0)
   {
 //
@@ -695,6 +703,7 @@ SetMemoryEncDec (
   ));
 PhysicalAddress += BIT30;
 Length -= BIT30;
+CBitChanged = TRUE;
   } else {
 //
 // We must split the page
@@ -749,6 +758,7 @@ SetMemoryEncDec (
   SetOrClearCBit (>Uint64, Mode);
   PhysicalAddress += BIT21;
   Length -= BIT21;
+  CBitChanged = TRUE;
 } else {
   //
   // We must split up this page into 4K pages
@@ -791,6 +801,7 @@ SetMemoryEncDec (
 SetOrClearCBit (>Uint64, Mode);
 PhysicalAddress += EFI_PAGE_SIZE;
 Length -= EFI_PAGE_SIZE;
+CBitChanged = TRUE;
   }
 }
   }
@@ -808,6 +819,13 @@ SetMemoryEncDec (
   //
   CpuFlushTlb();
 
+  //
+  // Notify Hypervisor on C-bit status
+  //
+  if (CBitChanged) {
+SetMemoryEncDecHypercall3 (OrigPhysicalAddress, EFI_SIZE_TO_PAGES(Size), 
!Mode);
+  }
+
 Done:
   //
   // Restore page table write protection, if any.
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 08/14] UefiCpuPkg/MpInitLib: temp removal of MpLib cleanup

2021-03-02 Thread Tobin Feldman-Fitzthum
The Migration Handdler is started using the Mp Service, which
is only designed to function during boot time. The MH needs
to run continuously. In the abscence of a generalized persitent
Mp Service, temporary alterations were made to keep the MH running.

Here, we skip registering the ExitBootServices callback that
would normally clean up the APs. Obviously this is not suitable
for production, as it does not generalize for multiple APs
(it leaves all APs untouched rather than just the MH) and it
introduces a weird dependency where the MpLib needs an
OVMF PCD.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |  2 ++
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c   | 21 ---
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
index 1771575c69..71cc968de8 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -39,6 +39,7 @@
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
   BaseLib
@@ -76,3 +77,4 @@
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase   ## 
SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard  ## 
CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase   ## 
CONSUMES
+  gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c 
b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 7839c24976..7d59ec4a92 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -569,14 +569,19 @@ InitMpGlobalData (
   );
   ASSERT_EFI_ERROR (Status);
 
-  Status = gBS->CreateEvent (
-  EVT_SIGNAL_EXIT_BOOT_SERVICES,
-  TPL_CALLBACK,
-  MpInitChangeApLoopCallback,
-  NULL,
-  
-  );
-  ASSERT_EFI_ERROR (Status);
+  //
+  // Workaround for persistent processes .
+  //
+  if (!PcdGetBool (PcdStartConfidentialMigrationHandler)) {
+Status = gBS->CreateEvent (
+EVT_SIGNAL_EXIT_BOOT_SERVICES,
+TPL_CALLBACK,
+MpInitChangeApLoopCallback,
+NULL,
+
+);
+ASSERT_EFI_ERROR (Status);
+  }
 
   Status = gBS->CreateEventEx (
   EVT_NOTIFY_SIGNAL,
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 05/14] OvmfPkg/PlatfomPei: Set Confidential Migration PCD

2021-03-02 Thread Tobin Feldman-Fitzthum
Confidential Migration relies on two boolean PCDs set from FW_CFG

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/PlatformPei/PlatformPei.inf |  2 ++
 OvmfPkg/PlatformPei/Platform.c  | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index 6ef77ba7bb..66e6fcfa4f 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -92,6 +92,8 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd
   gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
   gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase
+  gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+  gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
   gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 96468701e3..5926c8d414 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -275,6 +275,15 @@ NoexecDxeInitialization (
   UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdSetNxForStack);
 }
 
+VOID
+ConfidentialMigrationInitialization (
+  VOID
+  )
+{
+  UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdStartConfidentialMigrationHandler);
+  UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdIsConfidentialMigrationTarget);
+}
+
 VOID
 PciExBarInitialization (
   VOID
@@ -752,6 +761,7 @@ InitializePlatform (
 
   InstallClearCacheCallback ();
   AmdSevInitialize ();
+  ConfidentialMigrationInitialization ();
   MiscInitialization ();
   InstallFeatureControlCallback ();
 
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 02/14] OvmfPkg/PlatformPei: Mark SEC GHCB page in the page encrpytion bitmap.

2021-03-02 Thread Tobin Feldman-Fitzthum
From: Ashish Kalra 

Mark the SEC GHCB page that is mapped as unencrypted in
ResetVector code in the hypervisor page encryption bitmap.

Cc: Jordan Justen 
Cc: Laszlo Ersek 
Cc: Ard Biesheuvel 

Signed-off-by: Ashish Kalra 
---
 OvmfPkg/PlatformPei/AmdSev.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index dddffdebda..c72eeb37c5 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -52,6 +53,15 @@ AmdSevEsInitialize (
   PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
   ASSERT_RETURN_ERROR (PcdStatus);
 
+  //
+  // GHCB_BASE setup during reset-vector needs to be marked as
+  // decrypted in the hypervisor page encryption bitmap.
+  //
+  SetMemoryEncDecHypercall3 (FixedPcdGet32 (PcdOvmfSecGhcbBase),
+EFI_SIZE_TO_PAGES(FixedPcdGet32 (PcdOvmfSecGhcbSize)),
+FALSE
+);
+
   //
   // Allocate GHCB and per-CPU variable pages.
   //   Since the pages must survive across the UEFI to OS transition
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 04/14] OvmfPkg/AmdSev: Base for Confidential Migration Handler

2021-03-02 Thread Tobin Feldman-Fitzthum
Base enablement of DXE driver that supports confidential migration.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/OvmfPkg.dec   |  5 ++
 OvmfPkg/AmdSev/AmdSevX64.dsc  |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf  |  1 +
 .../ConfidentialMigrationDxe.inf  | 39 +
 .../ConfidentialMigrationDxe.c| 83 +++
 5 files changed, 129 insertions(+)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4450d78b91..402c3b61fa 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -324,6 +324,11 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0|UINT16|0x1b
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE|BOOLEAN|0x21
 
+  ## Set via FW_CFG to enable confidentialmigration as source or target.
+  #
+  
gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget|FALSE|BOOLEAN|0x46
+  
gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler|FALSE|BOOLEAN|0x47
+
   ## The IO port aperture shared by all PCI root bridges.
   #
   gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index ca21fd6e5f..fa68143663 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -787,6 +787,7 @@
 !endif
   OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
   OvmfPkg/AmdSev/Grub/Grub.inf
+  OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 !if $(BUILD_SHELL) == TRUE
   ShellPkg/Application/Shell/Shell.inf {
 
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index c0098502aa..6ef6dc89f2 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -273,6 +273,7 @@ INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
 INF  OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
 !endif
 INF OvmfPkg/AmdSev/SecretDxe/SecretDxe.inf
+INF OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 INF  OvmfPkg/AmdSev/Grub/Grub.inf
 !if $(BUILD_SHELL) == TRUE
 INF  ShellPkg/Application/Shell/Shell.inf
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
new file mode 100644
index 00..a4906a2451
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
@@ -0,0 +1,39 @@
+## @file
+#
+#  Copyright (C) 2021 IBM Corporation.
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 0x00010005
+  BASE_NAME  = ConfidentialMigration
+  FILE_GUID  = 5c2978f4-f175-434b-9e6c-9b03bd7e346f
+  MODULE_TYPE= DXE_DRIVER
+  VERSION_STRING = 1.0
+  ENTRY_POINT= LaunchMigrationHandler
+
+[Sources]
+  ConfidentialMigrationDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  MemoryAllocationLib
+  DebugLib
+  UefiBootServicesTableLib
+  MpInitLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiMpServiceProtocolGuid
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdIsConfidentialMigrationTarget
+  gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
+
+[Depex]
+  gEfiMpServiceProtocolGuid
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
new file mode 100644
index 00..6d9fe7043b
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -0,0 +1,83 @@
+/** @file
+  In-guest support for confidential migration
+
+  Copyright (C) 2021 IBM Coporation.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include 
+#include 
+#include 
+#include 
+#include 
+
+UINTN MigrationHandlerCpuIndex;
+
+VOID
+EFIAPI
+MigrationHandlerMain (
+  IN OUT VOID *Buffer
+  )
+{
+  DebugPrint (DEBUG_INFO,"MIGRATION Handler Started\n");
+}
+
+EFI_STATUS
+EFIAPI
+LaunchMigrationHandler (
+  IN EFI_HANDLE   ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_MP_SERVICES_PROTOCOL  *MpProto;
+  EFI_PROCESSOR_INFORMATION Tcb;
+  EFI_STATUSStatus;
+  UINTN NumProc;
+  UINTN NumEnabled;
+
+  gST = SystemTable;
+  gBS = gST->BootServices;
+  gRT = gST->RuntimeServices;
+
+  Status = EFI_NOT_STARTED;
+
+  if (!PcdGetBool(PcdStartConfidentialMigrationHandler)) {
+return 0;
+  }
+
+  //
+  // Use the MP Service protocol to start Migration Handler on AP
+  //
+  gBS->LocateProtocol (, NULL, (void**));
+  MpProto->GetNumberOfProcessors (MpProto, , );
+  if (NumProc < 2) {
+DebugPrint (DEBUG_ERROR,"Only one vCPU enabled. Please

[edk2-devel] [RFC PATCH 00/14] Firmware Support for Fast Live Migration for AMD SEV

2021-03-02 Thread Tobin Feldman-Fitzthum
This is a demonstration of fast migration for encrypted virtual machines
using a Migration Handler that lives in OVMF. This demo uses AMD SEV,
but the ideas may generalize to other confidential computing platforms.
With AMD SEV, guest memory is encrypted and the hypervisor cannot access
or move it. This makes migration tricky. In this demo, we show how the
HV can ask a Migration Handler (MH) in the firmware for an encrypted
page. The MH encrypts the page with a transport key prior to releasing
it to the HV. The target machine also runs an MH that decrypts the page
once it is passed in by the target HV. These patches are not ready for
production, but the are a full end-to-end solution that facilitates a
fast live migration between two SEV VMs.

Corresponding patches for QEMU have been posted my colleague Dov Murik
on qemu-devel. Our approach needs little kernel support, requiring only
one hypercall that the guest can use to mark a page as encrypted or
shared. This series includes updated patches from Ashish Kalra and
Brijesh Singh that allow OVMF to use this hypercall. 

The MH runs continuously in the guest, waiting for communication from
the HV. The HV starts an additional vCPU for the MH but does not expose
it to the guest OS via ACPI. We use the MpService to start the MH. The
MpService is only available at runtime and processes that are started by
it are usually cleaned up on ExitBootServices. Since we need the MH to
run continuously, we had to make some modifications. Ideally a feature
could be added to the MpService to allow for the starting of
long-running processes. Besides migration, this could support other
background processes that need to operate within the encryption
boundary. For now, we have included a handful of patches that modify the
MpService to allow the MH to keep running after ExitBootServices. These
are temporary. 

Ashish Kalra (2):
  OvmfPkg/PlatformPei: Mark SEC GHCB page in the page encrpytion bitmap.
  OvmfPkg/PlatformDxe: Add support for SEV live migration.

Brijesh Singh (1):
  OvmfPkg/BaseMemEncryptLib: Support to issue unencrypted hypercall

Dov Murik (1):
  OvmfPkg/AmdSev: Build page table for migration handler

Tobin Feldman-Fitzthum (10):
  OvmfPkg/AmdSev: Base for Confidential Migration Handler
  OvmfPkg/PlatfomPei: Set Confidential Migration PCD
  OvmfPkg/AmdSev: Setup Migration Handler Mailbox
  OvmfPkg/AmdSev: MH support for mailbox protocol
  UefiCpuPkg/MpInitLib: temp removal of MpLib cleanup
  UefiCpuPkg/MpInitLib: Allocate MP buffer as runtime memory
  UefiCpuPkg/CpuExceptionHandlerLib: Exception handling as runtime
memory
  OvmfPkg/AmdSev: Don't overwrite mailbox or pagetables
  OvmfPkg/AmdSev: Don't overwrite MH stack
  OvmfPkg/AmdSev: MH page encryption POC

 OvmfPkg/OvmfPkg.dec   |  11 +
 OvmfPkg/AmdSev/AmdSevX64.dsc  |   2 +
 OvmfPkg/AmdSev/AmdSevX64.fdf  |  13 +-
 .../ConfidentialMigrationDxe.inf  |  45 +++
 .../ConfidentialMigrationPei.inf  |  35 ++
 .../DxeMemEncryptSevLib.inf   |   1 +
 .../PeiMemEncryptSevLib.inf   |   1 +
 OvmfPkg/PlatformDxe/Platform.inf  |   2 +
 OvmfPkg/PlatformPei/PlatformPei.inf   |   2 +
 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf |   2 +
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf |   2 +
 OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h  | 235 +
 .../ConfidentialMigration/VirtualMemory.h | 177 ++
 OvmfPkg/Include/Guid/MemEncryptLib.h  |  16 +
 OvmfPkg/PlatformDxe/PlatformConfig.h  |   5 +
 .../ConfidentialMigrationDxe.c| 325 ++
 .../ConfidentialMigrationPei.c|  25 ++
 .../X64/PeiDxeVirtualMemory.c |  18 +
 OvmfPkg/PlatformDxe/AmdSev.c  |  99 ++
 OvmfPkg/PlatformDxe/Platform.c|   6 +
 OvmfPkg/PlatformPei/AmdSev.c  |  10 +
 OvmfPkg/PlatformPei/Platform.c|  10 +
 .../CpuExceptionHandlerLib/DxeException.c |   8 +-
 UefiCpuPkg/Library/MpInitLib/DxeMpLib.c   |  21 +-
 UefiCpuPkg/Library/MpInitLib/MpLib.c  |   7 +-
 25 files changed, 1061 insertions(+), 17 deletions(-)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.inf
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/MpLib.h
 create mode 100644 OvmfPkg/AmdSev/ConfidentialMigration/VirtualMemory.h
 create mode 100644 OvmfPkg/Include/Guid/MemEncryptLib.h
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
 create mode 100644 OvmfPkg/PlatformDxe/AmdSev.c

-- 
2.20.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#72353): https://edk2.groups.io/g/devel/message/72353

[edk2-devel] [RFC PATCH 06/14] OvmfPkg/AmdSev: Setup Migration Handler Mailbox

2021-03-02 Thread Tobin Feldman-Fitzthum
The migration handler communicates with the hypervisor using a
special mailbox, a page of shared memory where pending commands
can be written. Another shared page is used to pass the incoming
or outgoing guest memory pages. These pages are set aside in MEMFD,
which this patch expands, and reserved as runtime memory in
ConfidentialMigrationPei, which this patch introduces.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 OvmfPkg/OvmfPkg.dec   |  5 +++
 OvmfPkg/AmdSev/AmdSevX64.dsc  |  1 +
 OvmfPkg/AmdSev/AmdSevX64.fdf  | 12 ---
 .../ConfidentialMigrationPei.inf  | 35 +++
 .../ConfidentialMigrationPei.c| 25 +
 5 files changed, 74 insertions(+), 4 deletions(-)
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 create mode 100644 
OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 402c3b61fa..5c55e3c7c9 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -318,6 +318,11 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42
   gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43
 
+  ## Area used by the confidential migration handler to communicate with
+  # the hypervisor.
+  
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|0x0|UINT32|0x48
+  
gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize|0x0|UINT32|0x49
+
 [PcdsDynamic, PcdsDynamicEx]
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index fa68143663..4f748a0015 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -620,6 +620,7 @@
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
   UefiCpuPkg/CpuMpPei/CpuMpPei.inf
   OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+  OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 
 !if $(TPM_ENABLE) == TRUE
   OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
index 6ef6dc89f2..94468f2ca0 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
@@ -36,10 +36,10 @@ FV = SECFV
 
 [FD.MEMFD]
 BaseAddress   = $(MEMFD_BASE_ADDRESS)
-Size  = 0xD0
+Size  = 0xE0
 ErasePolarity = 1
 BlockSize = 0x1
-NumBlocks = 0xD0
+NumBlocks = 0xE0
 
 0x00|0x006000
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
@@ -68,11 +68,14 @@ 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.P
 0x01|0x01
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
 
-0x02|0x0E
+0x02|0x003000
+gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase|gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+
+0x12|0x0E
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
 FV = PEIFV
 
-0x10|0xC0
+0x20|0xC0
 
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
 FV = DXEFV
 
@@ -145,6 +148,7 @@ INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
 INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
 INF  OvmfPkg/AmdSev/SecretPei/SecretPei.inf
+INF  OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
 
 !if $(TPM_ENABLE) == TRUE
 INF  OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
new file mode 100644
index 00..918cf22abd
--- /dev/null
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.inf
@@ -0,0 +1,35 @@
+## @file
+#  PEI support for confidential migration.
+#
+#  Copyright (C) 2021 IBM Corporation.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION= 0x00010005
+  BASE_NAME  = ConfidentialMigration
+  FILE_GUID  = a747792e-71a1-4c24-84a9-a76a0a279878
+  MODULE_TYPE= PEIM
+  VERSION_STRING = 1.0
+  ENTRY_POINT= InitializeConfidentialMigrationPei
+
+[Sources]
+  ConfidentialMigrationPei.c
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  HobLib
+  PeimEntryPoint
+  PcdLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdConfidentialMigrationMailboxSize
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationPei.c
new

[edk2-devel] [RFC PATCH 09/14] UefiCpuPkg/MpInitLib: Allocate MP buffer as runtime memory

2021-03-02 Thread Tobin Feldman-Fitzthum
Another temporary change to support the persistence of the MH.
The Mp buffer needs to be allocated as runtime memory or it
may be overwritten by the OS.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 2 ++
 UefiCpuPkg/Library/MpInitLib/MpLib.c  | 7 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf 
b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
index 34abf25d43..0b26cf6aaf 100644
--- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
@@ -39,6 +39,7 @@
   MdePkg/MdePkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
   BaseLib
@@ -65,6 +66,7 @@
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled  ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase   ## 
SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase   ## CONSUMES
+  gUefiOvmfPkgTokenSpaceGuid.PcdStartConfidentialMigrationHandler
 
 [Ppis]
   gEdkiiPeiShadowMicrocodePpiGuid## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c 
b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 2568986d8c..0ca2858ca3 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1974,7 +1974,12 @@ MpInitLibInitialize (
   BufferSize += VolatileRegisters.Idtr.Limit + 1;
   BufferSize += sizeof (CPU_MP_DATA);
   BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* 
MaxLogicalProcessorNumber;
-  MpBuffer= AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
+  if (PcdGetBool (PcdStartConfidentialMigrationHandler)) {
+MpBuffer= AllocateRuntimePages (EFI_SIZE_TO_PAGES (BufferSize));
+  }
+  else {
+MpBuffer= AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
+  }
   ASSERT (MpBuffer != NULL);
   ZeroMem (MpBuffer, BufferSize);
   Buffer = (UINTN) MpBuffer;
-- 
2.20.1



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




[edk2-devel] [RFC PATCH 12/14] OvmfPkg/AmdSev: Don't overwrite mailbox or pagetables

2021-03-02 Thread Tobin Feldman-Fitzthum
While restoring pages, the MH should avoid overwriting its
pagetables or the mailbox it uses to communicate with the HV.

Signed-off-by: Tobin Feldman-Fitzthum 
---
 .../ConfidentialMigrationDxe.c| 22 +--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c 
b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
index 3df3b09732..f609e16f8d 100644
--- a/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
+++ b/OvmfPkg/AmdSev/ConfidentialMigration/ConfidentialMigrationDxe.c
@@ -128,6 +128,10 @@ MigrationHandlerMain (
   IN OUT VOID *Buffer
   )
 {
+  UINT64   mailbox_start;
+  UINT64   mailbox_end;
+  UINT64   pagetable_start;
+  UINT64   pagetable_end;
   UINT64   params_base;
   MH_COMMAND_PARAMETERS*params;
   VOID *page_va;
@@ -139,10 +143,16 @@ MigrationHandlerMain (
   //
   // Shared pages must be offset by UNENC_VIRT_ADDR_BASE.
   //
-  params_base = PcdGet32 (PcdConfidentialMigrationMailboxBase) + 
UNENC_VIRT_ADDR_BASE;
+  mailbox_start = PcdGet32 (PcdConfidentialMigrationMailboxBase);
+  params_base = mailbox_start + UNENC_VIRT_ADDR_BASE;
   params = (VOID *)params_base;
   page_va = (VOID *)params_base + 0x1000;
 
+  mailbox_end = mailbox_start + 2 * EFI_PAGE_SIZE;
+
+  pagetable_start = mMigrationHelperPageTables;
+  pagetable_end = pagetable_start + 11 * EFI_PAGE_SIZE;
+
   DisableInterrupts();
   params->go = 0;
 
@@ -163,7 +173,15 @@ MigrationHandlerMain (
   break;
 
 case MH_FUNC_RESTORE_PAGE:
-  CopyMem((VOID *)params->gpa, page_va, 4096);
+  //
+  // Don't import a page that covers the mailbox or pagetables.
+  //
+  if ((params->gpa >= mailbox_start && params->gpa < mailbox_end) ||
+  (params->gpa >= pagetable_start && params->gpa < pagetable_end)) {
+  }
+  else {
+CopyMem((VOID *)params->gpa, page_va, 4096);
+  }
   params->ret = MH_SUCCESS;
   break;
 
-- 
2.20.1



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