From: hanliyang <wojiaohanliy...@163.com>

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

In the case of launch a SEV-ES VM with just OVMF_CODE.fd, the validation
process in PlatformValidateNvVarStore will trigger MMIO NPF, and the #VC
handler will detect that mmio access is invalid because the mmio address
range of FlashNvVarStore is mapped as encrypted.

In the case of launch a SEV VM with both OVMF_CODE.fd and OVMF_VARS.fd,
PlatformValidateNvVarStore will fail to validate FlashNvVarStore because
the mapping of FlashNvVarStore address range is encrypted in the guest
but the corresponding data in system physical memory was not encrypted
by guest key.

We should map FlashNvVarStore address range as unencrypted for the above
cases.

Fixes: 4f173db8b45b ("OvmfPkg/PlatformInitLib: Add functions for 
EmuVariableNvStore")
Signed-off-by: hanliyang <wojiaohanliy...@163.com>
---
 OvmfPkg/PlatformPei/AmdSev.c        | 105 ++++++++++++++++++++++++++++
 OvmfPkg/PlatformPei/Platform.c      |   6 ++
 OvmfPkg/PlatformPei/Platform.h      |   6 ++
 OvmfPkg/PlatformPei/PlatformPei.inf |   1 +
 4 files changed, 118 insertions(+)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 8562787035..89f4c02b6a 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -575,3 +575,108 @@ SevInitializeRam (
       );
   }
 }
+
+/**
+  Prepared for FlashNvVarStore access.
+
+  **/
+VOID
+SevFlashNvVarStoreUpdateMapping (
+  IN UINTN  NvVarStoreBase,
+  IN UINTN  NvVarStoreSize
+  )
+{
+  volatile UINT8  *Ptr;
+
+  RETURN_STATUS  DecEncStatus;
+  UINT8          Offset;
+
+  DEBUG ((DEBUG_INFO, "%a\n", __func__));
+
+  if (!MemEncryptSevIsEnabled ()) {
+    return;
+  }
+
+  //
+  // In the case of launch a SEV-ES VM with just OVMF_CODE.fd, the
+  // validation process in PlatformValidateNvVarStore will trigger MMIO
+  // NPF, and the #VC handler will detect that mmio access is invalid
+  // because the mmio address range of FlashNvVarStore is mapped as
+  // encrypted. So, first we should update the mapping of address range
+  // of FlashNvVarStore as decrypted.
+  //
+  DEBUG (
+         (
+          DEBUG_INFO,
+          "%a: mapping FlashNvVarStore address range unencrypted [0x%p - 
0x%p]\n",
+          __func__,
+          (UINT8 *)NvVarStoreBase,
+          (UINT8 *)NvVarStoreBase + NvVarStoreSize - 1
+         )
+         );
+
+  DecEncStatus = MemEncryptSevClearMmioPageEncMask (
+                                                    0,
+                                                    NvVarStoreBase,
+                                                    EFI_SIZE_TO_PAGES 
(NvVarStoreSize)
+                                                    );
+  if (RETURN_ERROR (DecEncStatus)) {
+    DEBUG (
+           (
+            DEBUG_ERROR,
+            "%a: failed to map FlashNvStorage address range unencrypted\n",
+            __func__
+           )
+           );
+    ASSERT_RETURN_ERROR (DecEncStatus);
+  }
+
+  //
+  // Here, the first 16 bytes of FlashNvVarStore will be all zeros in
+  // the following cases:
+  //     a. Launch VM with just OVMF_CODE.fd
+  //     b. Launch VM with OVMF_CODE.fd and OVMF_VARS.fd
+  // In these cases, the access of FlashNvVarStore will be as expected.
+  //
+  // But if launch VM with just OVMF.fd, the first 16 bytes of
+  // FlashNvVarStore will be scrambled data because the data of
+  // FlashNvVarStore are encrypted by SEV API. In this case, we need
+  // mapping FlashNvVarStore address range as encrypted again, otherwise
+  // the validation of FlashNvVarStore will fail and trigger
+  // ASSERT (FALSE).
+  //
+  for (Offset = 0; Offset < 16; Offset++) {
+    Ptr = (UINT8 *)NvVarStoreBase + Offset;
+    if (*Ptr) {
+      break;
+    }
+  }
+
+  if (Offset == 16) {
+    return;
+  }
+
+  DEBUG (
+         (
+          DEBUG_INFO,
+          "%a: mapping FlashNvStorage address range encrypted\n",
+          __func__
+         )
+         );
+
+  DecEncStatus = MemEncryptSevSetPageEncMask (
+                                              0,
+                                              NvVarStoreBase,
+                                              EFI_SIZE_TO_PAGES 
(NvVarStoreSize)
+                                              );
+  if (RETURN_ERROR (DecEncStatus)) {
+    DEBUG (
+           (
+            DEBUG_ERROR,
+            "%a: failed to map FlashNvStorage address range encrypted\n",
+            __func__
+           )
+           );
+    ASSERT_RETURN_ERROR (DecEncStatus);
+  }
+}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 0114529778..bcb18dacac 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -224,6 +224,12 @@ ReserveEmuVariableNvStore (
   PcdStatus     = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
 
   if (FeaturePcdGet (PcdSecureBootSupported)) {
+    // update mapping of FlashNvVarStore address range
+    SevFlashNvVarStoreUpdateMapping (
+                                     PcdGet32 
(PcdOvmfFlashNvStorageVariableBase),
+                                     2 * PcdGet32 
(PcdFlashNvStorageFtwSpareSize)
+                                     );
+
     // restore emulated VarStore from pristine ROM copy
     PlatformInitEmuVariableNvStore ((VOID *)(UINTN)VariableStore);
   }
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index 0a59547cfc..b8ad8df1dc 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -111,4 +111,10 @@ SevInitializeRam (
   VOID
   );
 
+VOID
+SevFlashNvVarStoreUpdateMapping (
+  IN UINTN  NvVarStoreBase,
+  IN UINTN  NvVarStoreSize
+  );
+
 #endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf 
b/OvmfPkg/PlatformPei/PlatformPei.inf
index 0bb1a46291..a3dd3db72d 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -139,6 +139,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
-- 
2.25.1



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


Reply via email to