!296 sync 24.03 LTS patch list
From: @JiaboFeng Reviewed-by: @imxcc Signed-off-by: @imxcc
This commit is contained in:
commit
19e2f998a8
330
0068-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch
Normal file
330
0068-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
From ae4bf41d9c71137a21e7b8fc4aceca7212145b40 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
Date: Tue, 5 Apr 2022 16:09:28 +0000
|
||||||
|
Subject: [PATCH 1/9] OvmfPkg/BaseMemEncryptLib: Detect SEV live migration
|
||||||
|
feature.
|
||||||
|
|
||||||
|
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||||
|
|
||||||
|
Add support to check if we are running inside KVM HVM and
|
||||||
|
KVM HVM supports SEV Live Migration feature.
|
||||||
|
|
||||||
|
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||||
|
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||||
|
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/Include/Library/MemEncryptSevLib.h | 12 ++++
|
||||||
|
.../DxeMemEncryptSevLibInternal.c | 49 ++++++++++++++--
|
||||||
|
.../PeiDxeMemEncryptSevLibInternal.c | 58 +++++++++++++++++++
|
||||||
|
.../PeiDxeMemEncryptSevLibInternal.h | 31 ++++++++++
|
||||||
|
.../PeiMemEncryptSevLibInternal.c | 42 ++++++++++++++
|
||||||
|
.../SecMemEncryptSevLibInternal.c | 18 ++++++
|
||||||
|
6 files changed, 206 insertions(+), 4 deletions(-)
|
||||||
|
create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||||
|
index 4fa9c0d7..babec60d 100644
|
||||||
|
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||||
|
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||||
|
@@ -83,6 +83,18 @@ MemEncryptSevIsEnabled (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||||
|
+
|
||||||
|
+ @retval TRUE SEV live migration is enabled
|
||||||
|
+ @retval FALSE SEV live migration is not enabled
|
||||||
|
+**/
|
||||||
|
+BOOLEAN
|
||||||
|
+EFIAPI
|
||||||
|
+MemEncryptSevLiveMigrationIsEnabled (
|
||||||
|
+ VOID
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
This function clears memory encryption bit for the memory region specified by
|
||||||
|
BaseAddress and NumPages from the current page table context.
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||||
|
index 4aba0075..d80ebe2f 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||||
|
@@ -18,10 +18,14 @@
|
||||||
|
#include <Uefi/UefiBaseType.h>
|
||||||
|
#include <ConfidentialComputingGuestAttr.h>
|
||||||
|
|
||||||
|
-STATIC UINT64 mCurrentAttr = 0;
|
||||||
|
-STATIC BOOLEAN mCurrentAttrRead = FALSE;
|
||||||
|
-STATIC UINT64 mSevEncryptionMask = 0;
|
||||||
|
-STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;
|
||||||
|
+#include "PeiDxeMemEncryptSevLibInternal.h"
|
||||||
|
+
|
||||||
|
+STATIC UINT64 mCurrentAttr = 0;
|
||||||
|
+STATIC BOOLEAN mCurrentAttrRead = FALSE;
|
||||||
|
+STATIC UINT64 mSevEncryptionMask = 0;
|
||||||
|
+STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;
|
||||||
|
+STATIC BOOLEAN mSevLiveMigrationStatus = FALSE;
|
||||||
|
+STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The function check if the specified Attr is set.
|
||||||
|
@@ -111,6 +115,24 @@ MemEncryptSevSnpIsEnabled (
|
||||||
|
return ConfidentialComputingGuestHas (CCAttrAmdSevSnp);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Figures out if we are running inside KVM HVM and
|
||||||
|
+ KVM HVM supports SEV Live Migration feature.
|
||||||
|
+**/
|
||||||
|
+STATIC
|
||||||
|
+VOID
|
||||||
|
+EFIAPI
|
||||||
|
+InternalDetectSevLiveMigrationFeature (
|
||||||
|
+ VOID
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ if (KvmDetectSevLiveMigrationFeature ()) {
|
||||||
|
+ mSevLiveMigrationStatus = TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mSevLiveMigrationStatusChecked = TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Returns a boolean to indicate whether SEV-ES is enabled.
|
||||||
|
|
||||||
|
@@ -141,6 +163,25 @@ MemEncryptSevIsEnabled (
|
||||||
|
return ConfidentialComputingGuestHas (CCAttrAmdSev);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||||
|
+
|
||||||
|
+ @retval TRUE SEV live migration is enabled
|
||||||
|
+ @retval FALSE SEV live migration is not enabled
|
||||||
|
+**/
|
||||||
|
+BOOLEAN
|
||||||
|
+EFIAPI
|
||||||
|
+MemEncryptSevLiveMigrationIsEnabled (
|
||||||
|
+ VOID
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ if (!mSevLiveMigrationStatusChecked) {
|
||||||
|
+ InternalDetectSevLiveMigrationFeature ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return mSevLiveMigrationStatus;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Returns the SEV encryption mask.
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
|
||||||
|
index 78ea16ae..868392f7 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.c
|
||||||
|
@@ -16,6 +16,8 @@
|
||||||
|
#include <Register/SmramSaveStateMap.h>
|
||||||
|
#include <Uefi/UefiBaseType.h>
|
||||||
|
|
||||||
|
+#include "PeiDxeMemEncryptSevLibInternal.h"
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM
|
||||||
|
Save State Map.
|
||||||
|
@@ -61,3 +63,59 @@ MemEncryptSevLocateInitialSmramSaveStateMapPages (
|
||||||
|
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Figures out if we are running inside KVM HVM and
|
||||||
|
+ KVM HVM supports SEV Live Migration feature.
|
||||||
|
+
|
||||||
|
+ @retval TRUE SEV live migration is supported.
|
||||||
|
+ @retval FALSE SEV live migration is not supported.
|
||||||
|
+**/
|
||||||
|
+BOOLEAN
|
||||||
|
+EFIAPI
|
||||||
|
+KvmDetectSevLiveMigrationFeature (
|
||||||
|
+ VOID
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ CHAR8 Signature[13];
|
||||||
|
+ UINT32 mKvmLeaf;
|
||||||
|
+ UINT32 RegEax;
|
||||||
|
+ UINT32 RegEbx;
|
||||||
|
+ UINT32 RegEcx;
|
||||||
|
+ UINT32 RegEdx;
|
||||||
|
+
|
||||||
|
+ Signature[12] = '\0';
|
||||||
|
+ for (mKvmLeaf = 0x40000000; mKvmLeaf < 0x40010000; mKvmLeaf += 0x100) {
|
||||||
|
+ AsmCpuid (
|
||||||
|
+ mKvmLeaf,
|
||||||
|
+ NULL,
|
||||||
|
+ (UINT32 *)&Signature[0],
|
||||||
|
+ (UINT32 *)&Signature[4],
|
||||||
|
+ (UINT32 *)&Signature[8]
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ if (AsciiStrCmp (Signature, "KVMKVMKVM") == 0) {
|
||||||
|
+ DEBUG ((
|
||||||
|
+ DEBUG_INFO,
|
||||||
|
+ "%a: KVM Detected, signature = %a\n",
|
||||||
|
+ __FUNCTION__,
|
||||||
|
+ Signature
|
||||||
|
+ ));
|
||||||
|
+
|
||||||
|
+ RegEax = mKvmLeaf + 1;
|
||||||
|
+ RegEcx = 0;
|
||||||
|
+ AsmCpuid (mKvmLeaf + 1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
|
||||||
|
+ if ((RegEax & KVM_FEATURE_MIGRATION_CONTROL) != 0) {
|
||||||
|
+ DEBUG ((
|
||||||
|
+ DEBUG_INFO,
|
||||||
|
+ "%a: SEV Live Migration feature supported\n",
|
||||||
|
+ __FUNCTION__
|
||||||
|
+ ));
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return FALSE;
|
||||||
|
+}
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..b0ef053c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiDxeMemEncryptSevLibInternal.h
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+/** @file
|
||||||
|
+
|
||||||
|
+ Secure Encrypted Virtualization (SEV) library helper function
|
||||||
|
+
|
||||||
|
+ Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
|
||||||
|
+
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#ifndef PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_
|
||||||
|
+#define PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_
|
||||||
|
+
|
||||||
|
+#include <Library/BaseLib.h>
|
||||||
|
+
|
||||||
|
+#define KVM_FEATURE_MIGRATION_CONTROL BIT17
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Figures out if we are running inside KVM HVM and
|
||||||
|
+ KVM HVM supports SEV Live Migration feature.
|
||||||
|
+
|
||||||
|
+ @retval TRUE SEV live migration is supported.
|
||||||
|
+ @retval FALSE SEV live migration is not supported.
|
||||||
|
+**/
|
||||||
|
+BOOLEAN
|
||||||
|
+EFIAPI
|
||||||
|
+KvmDetectSevLiveMigrationFeature (
|
||||||
|
+ VOID
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+#endif // PEI_DXE_MEM_ENCRYPT_SEV_LIB_INTERNAL_H_
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
|
||||||
|
index 41d1246a..307087a1 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
|
||||||
|
@@ -17,6 +17,11 @@
|
||||||
|
#include <Register/Cpuid.h>
|
||||||
|
#include <Uefi/UefiBaseType.h>
|
||||||
|
|
||||||
|
+#include "PeiDxeMemEncryptSevLibInternal.h"
|
||||||
|
+
|
||||||
|
+STATIC BOOLEAN mSevLiveMigrationStatus = FALSE;
|
||||||
|
+STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE;
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Read the workarea to determine whether SEV is enabled. If enabled,
|
||||||
|
then return the SevEsWorkArea pointer.
|
||||||
|
@@ -83,6 +88,24 @@ MemEncryptSevSnpIsEnabled (
|
||||||
|
return Msr.Bits.SevSnpBit ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Figures out if we are running inside KVM HVM and
|
||||||
|
+ KVM HVM supports SEV Live Migration feature.
|
||||||
|
+**/
|
||||||
|
+STATIC
|
||||||
|
+VOID
|
||||||
|
+EFIAPI
|
||||||
|
+InternalDetectSevLiveMigrationFeature (
|
||||||
|
+ VOID
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ if (KvmDetectSevLiveMigrationFeature ()) {
|
||||||
|
+ mSevLiveMigrationStatus = TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mSevLiveMigrationStatusChecked = TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Returns a boolean to indicate whether SEV-ES is enabled.
|
||||||
|
|
||||||
|
@@ -121,6 +144,25 @@ MemEncryptSevIsEnabled (
|
||||||
|
return Msr.Bits.SevBit ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||||
|
+
|
||||||
|
+ @retval TRUE SEV live migration is enabled
|
||||||
|
+ @retval FALSE SEV live migration is not enabled
|
||||||
|
+**/
|
||||||
|
+BOOLEAN
|
||||||
|
+EFIAPI
|
||||||
|
+MemEncryptSevLiveMigrationIsEnabled (
|
||||||
|
+ VOID
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ if (!mSevLiveMigrationStatusChecked) {
|
||||||
|
+ InternalDetectSevLiveMigrationFeature ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return mSevLiveMigrationStatus;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Returns the SEV encryption mask.
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||||
|
index 27148c7e..9142ac40 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||||
|
@@ -121,6 +121,24 @@ MemEncryptSevIsEnabled (
|
||||||
|
return Msr.Bits.SevBit ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Returns a boolean to indicate whether SEV live migration is enabled.
|
||||||
|
+
|
||||||
|
+ @retval TRUE SEV live migration is enabled
|
||||||
|
+ @retval FALSE SEV live migration is not enabled
|
||||||
|
+**/
|
||||||
|
+BOOLEAN
|
||||||
|
+EFIAPI
|
||||||
|
+MemEncryptSevLiveMigrationIsEnabled (
|
||||||
|
+ VOID
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ //
|
||||||
|
+ // Not used in SEC phase.
|
||||||
|
+ //
|
||||||
|
+ return FALSE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Returns the SEV encryption mask.
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
301
0069-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch
Normal file
301
0069-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
From 2c000372cab80ab68a8672138c8d0f5cb1ae43d9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
Date: Tue, 5 Apr 2022 16:23:53 +0000
|
||||||
|
Subject: [PATCH 2/9] OvmfPkg/BaseMemEncryptLib: Hypercall API for page
|
||||||
|
encryption state change
|
||||||
|
|
||||||
|
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||||
|
|
||||||
|
Add API to issue hypercall on page encryption state change.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
This hypercall is used to notify hypervisor when the page's
|
||||||
|
encryption state changes.
|
||||||
|
|
||||||
|
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||||
|
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||||
|
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||||
|
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/Include/Library/MemEncryptSevLib.h | 52 +++++++++++++++
|
||||||
|
.../DxeMemEncryptSevLib.inf | 1 +
|
||||||
|
.../Ia32/MemEncryptSevLib.c | 27 ++++++++
|
||||||
|
.../PeiMemEncryptSevLib.inf | 1 +
|
||||||
|
.../SecMemEncryptSevLibInternal.c | 20 ++++++
|
||||||
|
.../X64/AsmHelperStub.nasm | 33 ++++++++++
|
||||||
|
.../X64/MemEncryptSevLib.c | 66 +++++++++++++++++++
|
||||||
|
7 files changed, 200 insertions(+)
|
||||||
|
create mode 100644 OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||||
|
index babec60d..b60496c2 100644
|
||||||
|
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||||
|
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
|
||||||
|
@@ -240,4 +240,56 @@ MemEncryptSevSnpPreValidateSystemRam (
|
||||||
|
IN UINTN NumPages
|
||||||
|
);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ This hypercall is used to notify hypervisor when the page's encryption
|
||||||
|
+ state changes.
|
||||||
|
+
|
||||||
|
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||||
|
+ of a memory region.
|
||||||
|
+ @param[in] Pages Number of pages in memory region.
|
||||||
|
+ @param[in] IsEncrypted Encrypted or Decrypted.
|
||||||
|
+
|
||||||
|
+ @retval RETURN_SUCCESS Hypercall returned success.
|
||||||
|
+ @retval RETURN_UNSUPPORTED Hypercall not supported.
|
||||||
|
+ @retval RETURN_NO_MAPPING Hypercall returned error.
|
||||||
|
+**/
|
||||||
|
+RETURN_STATUS
|
||||||
|
+EFIAPI
|
||||||
|
+SetMemoryEncDecHypercall3 (
|
||||||
|
+ IN UINTN PhysicalAddress,
|
||||||
|
+ IN UINTN Pages,
|
||||||
|
+ IN BOOLEAN IsEncrypted
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+#define KVM_HC_MAP_GPA_RANGE 12
|
||||||
|
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0
|
||||||
|
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M BIT0
|
||||||
|
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_1G BIT1
|
||||||
|
+#define KVM_MAP_GPA_RANGE_ENC_STATE(n) ((n) << 4)
|
||||||
|
+#define KVM_MAP_GPA_RANGE_ENCRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(1)
|
||||||
|
+#define KVM_MAP_GPA_RANGE_DECRYPTED KVM_MAP_GPA_RANGE_ENC_STATE(0)
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ Interface exposed by the ASM implementation of the core hypercall
|
||||||
|
+
|
||||||
|
+ @param[in] HypercallNum KVM_HC_MAP_GPA_RANGE hypercall.
|
||||||
|
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||||
|
+ of a memory region.
|
||||||
|
+ @param[in] Pages Number of pages in memory region.
|
||||||
|
+ @param[in] Attributes Bits 3:0 - preferred page size encoding,
|
||||||
|
+ 0 = 4kb, 1 = 2mb, 2 = 1gb, etc...
|
||||||
|
+ Bit 4 - plaintext = 0, encrypted = 1
|
||||||
|
+ Bits 63:5 - reserved (must be zero)
|
||||||
|
+
|
||||||
|
+ @retval Hypercall returned status.
|
||||||
|
+**/
|
||||||
|
+UINTN
|
||||||
|
+EFIAPI
|
||||||
|
+SetMemoryEncDecHypercall3AsmStub (
|
||||||
|
+ IN UINTN HypercallNum,
|
||||||
|
+ IN UINTN PhysicalAddress,
|
||||||
|
+ IN UINTN Pages,
|
||||||
|
+ IN UINTN Attributes
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
#endif // _MEM_ENCRYPT_SEV_LIB_H_
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||||
|
index 3a1d3089..4d32fae6 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||||
|
@@ -40,6 +40,7 @@
|
||||||
|
X64/SnpPageStateChangeInternal.c
|
||||||
|
X64/VirtualMemory.c
|
||||||
|
X64/VirtualMemory.h
|
||||||
|
+ X64/AsmHelperStub.nasm
|
||||||
|
|
||||||
|
[Sources.IA32]
|
||||||
|
Ia32/MemEncryptSevLib.c
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
|
||||||
|
index f92299fc..c1c10a61 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/Ia32/MemEncryptSevLib.c
|
||||||
|
@@ -153,3 +153,30 @@ MemEncryptSevSnpPreValidateSystemRam (
|
||||||
|
{
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ This hyercall is used to notify hypervisor when the page's encryption
|
||||||
|
+ state changes.
|
||||||
|
+
|
||||||
|
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||||
|
+ of a memory region.
|
||||||
|
+ @param[in] Pages Number of Pages in the memory region.
|
||||||
|
+ @param[in] IsEncrypted Encrypted or Decrypted.
|
||||||
|
+
|
||||||
|
+ @retval RETURN_SUCCESS Hypercall returned success.
|
||||||
|
+ @retval RETURN_UNSUPPORTED Hypercall not supported.
|
||||||
|
+ @retval RETURN_NO_MAPPING Hypercall returned error.
|
||||||
|
+**/
|
||||||
|
+RETURN_STATUS
|
||||||
|
+EFIAPI
|
||||||
|
+SetMemoryEncDecHypercall3 (
|
||||||
|
+ IN UINTN PhysicalAddress,
|
||||||
|
+ IN UINTN Pages,
|
||||||
|
+ IN BOOLEAN IsEncrypted
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ //
|
||||||
|
+ // Memory encryption bit is not accessible in 32-bit mode
|
||||||
|
+ //
|
||||||
|
+ return RETURN_UNSUPPORTED;
|
||||||
|
+}
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
|
||||||
|
index 8f56783d..3f11f06a 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
|
||||||
|
@@ -40,6 +40,7 @@
|
||||||
|
X64/SnpPageStateChangeInternal.c
|
||||||
|
X64/VirtualMemory.c
|
||||||
|
X64/VirtualMemory.h
|
||||||
|
+ X64/AsmHelperStub.nasm
|
||||||
|
|
||||||
|
[Sources.IA32]
|
||||||
|
Ia32/MemEncryptSevLib.c
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||||
|
index 9142ac40..ffb22a08 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
|
||||||
|
@@ -139,6 +139,26 @@ MemEncryptSevLiveMigrationIsEnabled (
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ Interface exposed by the ASM implementation of the core hypercall
|
||||||
|
+
|
||||||
|
+ @retval Hypercall returned status.
|
||||||
|
+**/
|
||||||
|
+UINTN
|
||||||
|
+EFIAPI
|
||||||
|
+SetMemoryEncDecHypercall3AsmStub (
|
||||||
|
+ IN UINTN HypercallNum,
|
||||||
|
+ IN UINTN PhysicalAddress,
|
||||||
|
+ IN UINTN Pages,
|
||||||
|
+ IN UINTN Attributes
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ //
|
||||||
|
+ // Not used in SEC phase.
|
||||||
|
+ //
|
||||||
|
+ return RETURN_UNSUPPORTED;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Returns the SEV encryption mask.
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..0ec35dd9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/AsmHelperStub.nasm
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+/** @file
|
||||||
|
+
|
||||||
|
+ ASM helper stub to invoke hypercall
|
||||||
|
+
|
||||||
|
+ Copyright (c) 2021, AMD Incorporated. All rights reserved.<BR>
|
||||||
|
+
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+DEFAULT REL
|
||||||
|
+SECTION .text
|
||||||
|
+
|
||||||
|
+; UINTN
|
||||||
|
+; EFIAPI
|
||||||
|
+; SetMemoryEncDecHypercall3AsmStub (
|
||||||
|
+; IN UINTN HypercallNum,
|
||||||
|
+; IN UINTN Arg1,
|
||||||
|
+; IN UINTN Arg2,
|
||||||
|
+; IN UINTN Arg3
|
||||||
|
+; );
|
||||||
|
+global ASM_PFX(SetMemoryEncDecHypercall3AsmStub)
|
||||||
|
+ASM_PFX(SetMemoryEncDecHypercall3AsmStub):
|
||||||
|
+ ; UEFI calling conventions require RBX to
|
||||||
|
+ ; be nonvolatile/callee-saved.
|
||||||
|
+ push rbx
|
||||||
|
+ mov rax, rcx ; Copy HypercallNumber to rax
|
||||||
|
+ mov rbx, rdx ; Copy Arg1 to the register expected by KVM
|
||||||
|
+ mov rcx, r8 ; Copy Arg2 to register expected by KVM
|
||||||
|
+ mov rdx, r9 ; Copy Arg3 to register expected by KVM
|
||||||
|
+ vmmcall ; Call VMMCALL
|
||||||
|
+ pop rbx
|
||||||
|
+ ret
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||||
|
index e7c703bb..a64ff2a5 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||||
|
@@ -142,3 +142,69 @@ MemEncryptSevClearMmioPageEncMask (
|
||||||
|
EFI_PAGES_TO_SIZE (NumPages)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ This hyercall is used to notify hypervisor when the page's encryption
|
||||||
|
+ state changes.
|
||||||
|
+
|
||||||
|
+ @param[in] PhysicalAddress The physical address that is the start address
|
||||||
|
+ of a memory region.
|
||||||
|
+ @param[in] Pages Number of Pages in the memory region.
|
||||||
|
+ @param[in] IsEncrypted Encrypted or Decrypted.
|
||||||
|
+
|
||||||
|
+ @retval RETURN_SUCCESS Hypercall returned success.
|
||||||
|
+ @retval RETURN_UNSUPPORTED Hypercall not supported.
|
||||||
|
+ @retval RETURN_NO_MAPPING Hypercall returned error.
|
||||||
|
+**/
|
||||||
|
+RETURN_STATUS
|
||||||
|
+EFIAPI
|
||||||
|
+SetMemoryEncDecHypercall3 (
|
||||||
|
+ IN UINTN PhysicalAddress,
|
||||||
|
+ IN UINTN Pages,
|
||||||
|
+ IN BOOLEAN IsEncrypted
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ RETURN_STATUS Ret;
|
||||||
|
+ UINTN Error;
|
||||||
|
+ UINTN EncryptState;
|
||||||
|
+
|
||||||
|
+ Ret = RETURN_UNSUPPORTED;
|
||||||
|
+
|
||||||
|
+ if (MemEncryptSevLiveMigrationIsEnabled ()) {
|
||||||
|
+ Ret = RETURN_SUCCESS;
|
||||||
|
+ //
|
||||||
|
+ // The encryption bit is set/clear on the smallest page size, hence
|
||||||
|
+ // use the 4k page size in MAP_GPA_RANGE hypercall below.
|
||||||
|
+ //
|
||||||
|
+ // Also, when the GCD map is being walked and the c-bit being cleared
|
||||||
|
+ // from MMIO and NonExistent memory spaces, the physical address
|
||||||
|
+ // range being passed may not be page-aligned and adding an assert
|
||||||
|
+ // here prevents booting. Hence, rounding it down when calling
|
||||||
|
+ // SetMemoryEncDecHypercall3AsmStub below.
|
||||||
|
+ //
|
||||||
|
+
|
||||||
|
+ EncryptState = IsEncrypted ? KVM_MAP_GPA_RANGE_ENCRYPTED :
|
||||||
|
+ KVM_MAP_GPA_RANGE_DECRYPTED;
|
||||||
|
+
|
||||||
|
+ Error = SetMemoryEncDecHypercall3AsmStub (
|
||||||
|
+ KVM_HC_MAP_GPA_RANGE,
|
||||||
|
+ PhysicalAddress & ~EFI_PAGE_MASK,
|
||||||
|
+ Pages,
|
||||||
|
+ KVM_MAP_GPA_RANGE_PAGE_SZ_4K | EncryptState
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ if (Error != 0) {
|
||||||
|
+ DEBUG ((
|
||||||
|
+ DEBUG_ERROR,
|
||||||
|
+ "SetMemoryEncDecHypercall3 failed, Phys = %x, Pages = %d, Err = %Ld\n",
|
||||||
|
+ PhysicalAddress,
|
||||||
|
+ Pages,
|
||||||
|
+ (INT64)Error
|
||||||
|
+ ));
|
||||||
|
+
|
||||||
|
+ Ret = RETURN_NO_MAPPING;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return Ret;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
From 481f0a191fc03e79bbb52b08c1d4890b6331e68d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
Date: Tue, 5 Apr 2022 16:26:02 +0000
|
||||||
|
Subject: [PATCH 3/9] OvmfPkg/BaseMemEncryptLib: Invoke page encryption state
|
||||||
|
change hypercall
|
||||||
|
|
||||||
|
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||||
|
|
||||||
|
Invoke the hypercall API to notify hypervisor when the page's
|
||||||
|
encryption state changes.
|
||||||
|
|
||||||
|
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||||
|
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||||
|
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||||
|
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
---
|
||||||
|
.../X64/PeiDxeVirtualMemory.c | 16 ++++++++++++++++
|
||||||
|
1 file changed, 16 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||||
|
index a49cf125..42e3b03f 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||||
|
@@ -727,6 +727,7 @@ SetMemoryEncDec (
|
||||||
|
UINT64 PgTableMask;
|
||||||
|
UINT64 AddressEncMask;
|
||||||
|
BOOLEAN IsWpEnabled;
|
||||||
|
+ BOOLEAN CBitChanged;
|
||||||
|
UINTN OrigLength;
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
PHYSICAL_ADDRESS PageAddress;
|
||||||
|
@@ -800,6 +801,7 @@ SetMemoryEncDec (
|
||||||
|
// Save the specified length and physical address (we need it later).
|
||||||
|
//
|
||||||
|
OrigLength = Length;
|
||||||
|
+ CBitChanged = FALSE;
|
||||||
|
OrigPhysicalAddress = PhysicalAddress;
|
||||||
|
|
||||||
|
while (Length != 0) {
|
||||||
|
@@ -860,6 +862,7 @@ SetMemoryEncDec (
|
||||||
|
));
|
||||||
|
PhysicalAddress += BIT30;
|
||||||
|
Length -= BIT30;
|
||||||
|
+ CBitChanged = TRUE;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// We must split the page
|
||||||
|
@@ -915,6 +918,7 @@ SetMemoryEncDec (
|
||||||
|
SetOrClearCBit (&PageDirectory2MEntry->Uint64, Mode);
|
||||||
|
PhysicalAddress += BIT21;
|
||||||
|
Length -= BIT21;
|
||||||
|
+ CBitChanged = TRUE;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// We must split up this page into 4K pages
|
||||||
|
@@ -958,6 +962,7 @@ SetMemoryEncDec (
|
||||||
|
SetOrClearCBit (&PageTableEntry->Uint64, Mode);
|
||||||
|
PhysicalAddress += EFI_PAGE_SIZE;
|
||||||
|
Length -= EFI_PAGE_SIZE;
|
||||||
|
+ CBitChanged = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -990,6 +995,17 @@ SetMemoryEncDec (
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ //
|
||||||
|
+ // Notify Hypervisor on C-bit status
|
||||||
|
+ //
|
||||||
|
+ if (CBitChanged) {
|
||||||
|
+ Status = SetMemoryEncDecHypercall3 (
|
||||||
|
+ OrigPhysicalAddress,
|
||||||
|
+ EFI_SIZE_TO_PAGES (OrigLength),
|
||||||
|
+ (Mode == SetCBit) ? TRUE : FALSE
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
Done:
|
||||||
|
//
|
||||||
|
// Restore page table write protection, if any.
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
From 1058be0934a043804f2ae0b8ea1aa42454dc0eb8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
Date: Tue, 5 Apr 2022 16:27:26 +0000
|
||||||
|
Subject: [PATCH 4/9] OvmfPkg/VmgExitLib: Encryption state change hypercall
|
||||||
|
support in VC handler
|
||||||
|
|
||||||
|
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||||
|
|
||||||
|
Make the #VC handler aware of the page encryption state
|
||||||
|
change hypercall by adding support to check KVM_HC_MAP_GPA_RANGE
|
||||||
|
hypercall and add the additional register values used by
|
||||||
|
hypercall in the GHCB.
|
||||||
|
|
||||||
|
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||||
|
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||||
|
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 13 +++++++++++++
|
||||||
|
1 file changed, 13 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
|
||||||
|
index 0fc30f7b..5c9a9085 100644
|
||||||
|
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
|
||||||
|
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
|
||||||
|
@@ -677,6 +677,19 @@ VmmCallExit (
|
||||||
|
Ghcb->SaveArea.Cpl = (UINT8)(Regs->Cs & 0x3);
|
||||||
|
CcExitVmgSetOffsetValid (Ghcb, GhcbCpl);
|
||||||
|
|
||||||
|
+ if (Regs->Rax == KVM_HC_MAP_GPA_RANGE) {
|
||||||
|
+ //
|
||||||
|
+ // KVM_HC_MAP_GPA_RANGE hypercall requires these
|
||||||
|
+ // extra registers.
|
||||||
|
+ //
|
||||||
|
+ Ghcb->SaveArea.Rbx = Regs->Rbx;
|
||||||
|
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRbx);
|
||||||
|
+ Ghcb->SaveArea.Rcx = Regs->Rcx;
|
||||||
|
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);
|
||||||
|
+ Ghcb->SaveArea.Rdx = Regs->Rdx;
|
||||||
|
+ CcExitVmgSetOffsetValid (Ghcb, GhcbRdx);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
Status = CcExitVmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0);
|
||||||
|
if (Status != 0) {
|
||||||
|
return Status;
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
From 16e7adce62f7c28cc1823229b40a27493737cae6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
Date: Tue, 5 Apr 2022 16:30:54 +0000
|
||||||
|
Subject: [PATCH 5/9] OvmfPkg/PlatformPei: Mark SEC GHCB page as unencrypted
|
||||||
|
via hypercall
|
||||||
|
|
||||||
|
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||||
|
|
||||||
|
Mark the SEC GHCB page (that is mapped as unencrypted in
|
||||||
|
ResetVector code) in the hypervisor's guest page encryption
|
||||||
|
state tracking.
|
||||||
|
|
||||||
|
Cc: Jordan Justen <jordan.l.justen@intel.com>
|
||||||
|
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
|
||||||
|
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/PlatformPei/AmdSev.c | 11 +++++++++++
|
||||||
|
1 file changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
|
||||||
|
index e6b602d7..553e841e 100644
|
||||||
|
--- a/OvmfPkg/PlatformPei/AmdSev.c
|
||||||
|
+++ b/OvmfPkg/PlatformPei/AmdSev.c
|
||||||
|
@@ -229,6 +229,17 @@ AmdSevEsInitialize (
|
||||||
|
Status = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
|
||||||
|
ASSERT_RETURN_ERROR (Status);
|
||||||
|
|
||||||
|
+ //
|
||||||
|
+ // The SEC Ghcb setup during reset-vector needs to be marked as
|
||||||
|
+ // decrypted in the hypervisor's guest page encryption state
|
||||||
|
+ // tracking.
|
||||||
|
+ //
|
||||||
|
+ 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.25.1
|
||||||
|
|
||||||
196
0073-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch
Normal file
196
0073-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
From 8d82fca148d9564b666b5f4185a0e78e1f77e230 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
Date: Tue, 5 Apr 2022 16:40:03 +0000
|
||||||
|
Subject: [PATCH 6/9] OvmfPkg/AmdSevDxe: Add support for SEV live migration.
|
||||||
|
|
||||||
|
cherry-picked from https://patchew.org/EDK2/cover.1629380011.git.ashish.kalra@amd.com .
|
||||||
|
|
||||||
|
Check for SEV live migration feature support, if detected
|
||||||
|
setup a new UEFI enviroment variable to indicate OVMF
|
||||||
|
support for SEV live migration.
|
||||||
|
|
||||||
|
This environment variable is created by UEFI but consumed
|
||||||
|
by the (guest) linux kernel. This is actually part of a
|
||||||
|
3-way negotiation of the live migration feature between
|
||||||
|
hypervisor, guest OVMF and guest kernel. Host indicates
|
||||||
|
support for live migration, which is detected by OVMF
|
||||||
|
and correspondingly OVMF sets this SetLiveMigrationEnabled
|
||||||
|
UEFI variable, which is read by the guest kernel and it
|
||||||
|
indicates to the guest kernel that both host and OVMF
|
||||||
|
support and have enabled the live migration feature.
|
||||||
|
|
||||||
|
The new runtime UEFI environment variable is set via the
|
||||||
|
notification function registered for the
|
||||||
|
EFI_END_OF_DXE_EVENT_GROUP_GUID event in AmdSevDxe driver.
|
||||||
|
|
||||||
|
AmdSevDxe module is an apriori driver so it gets loaded between PEI
|
||||||
|
and DXE phases and the SetVariable call will fail at the driver's
|
||||||
|
entry point as the Variable DXE module is still not loaded yet.
|
||||||
|
So we need to wait for an event notification which is signaled
|
||||||
|
after the Variable DXE module is loaded, hence, using the
|
||||||
|
EndOfDxe event notification to make this call.
|
||||||
|
|
||||||
|
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/AmdSevDxe/AmdSevDxe.c | 67 ++++++++++++++++++++++
|
||||||
|
OvmfPkg/AmdSevDxe/AmdSevDxe.inf | 4 ++
|
||||||
|
OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h | 20 +++++++
|
||||||
|
OvmfPkg/OvmfPkg.dec | 1 +
|
||||||
|
4 files changed, 92 insertions(+)
|
||||||
|
create mode 100644 OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
|
||||||
|
index db3675ae..e3a8049d 100644
|
||||||
|
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c
|
||||||
|
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c
|
||||||
|
@@ -15,10 +15,13 @@
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/DxeServicesTableLib.h>
|
||||||
|
+#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include <Library/MemEncryptSevLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Guid/ConfidentialComputingSevSnpBlob.h>
|
||||||
|
+#include <Guid/AmdSevMemEncryptLib.h>
|
||||||
|
+#include <Guid/EventGroup.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Pi/PrePiDxeCis.h>
|
||||||
|
#include <Protocol/SevMemoryAcceptance.h>
|
||||||
|
@@ -191,6 +194,39 @@ STATIC EDKII_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = {
|
||||||
|
AmdSevMemoryAccept
|
||||||
|
};
|
||||||
|
|
||||||
|
+STATIC
|
||||||
|
+VOID
|
||||||
|
+EFIAPI
|
||||||
|
+AmdSevDxeOnEndOfDxe (
|
||||||
|
+ IN EFI_EVENT Event,
|
||||||
|
+ IN VOID *EventToSignal
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS Status;
|
||||||
|
+ BOOLEAN SevLiveMigrationEnabled;
|
||||||
|
+
|
||||||
|
+ SevLiveMigrationEnabled = MemEncryptSevLiveMigrationIsEnabled ();
|
||||||
|
+
|
||||||
|
+ if (SevLiveMigrationEnabled) {
|
||||||
|
+ Status = gRT->SetVariable (
|
||||||
|
+ L"SevLiveMigrationEnabled",
|
||||||
|
+ &gAmdSevMemEncryptGuid,
|
||||||
|
+ EFI_VARIABLE_NON_VOLATILE |
|
||||||
|
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
+ EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
+ sizeof SevLiveMigrationEnabled,
|
||||||
|
+ &SevLiveMigrationEnabled
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ DEBUG ((
|
||||||
|
+ DEBUG_INFO,
|
||||||
|
+ "%a: Setting SevLiveMigrationEnabled variable, status = %lx\n",
|
||||||
|
+ __FUNCTION__,
|
||||||
|
+ Status
|
||||||
|
+ ));
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
AmdSevDxeEntryPoint (
|
||||||
|
@@ -203,6 +239,7 @@ AmdSevDxeEntryPoint (
|
||||||
|
UINTN NumEntries;
|
||||||
|
UINTN Index;
|
||||||
|
CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION *SnpBootDxeTable;
|
||||||
|
+ EFI_EVENT Event;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do nothing when SEV is not enabled
|
||||||
|
@@ -361,5 +398,35 @@ AmdSevDxeEntryPoint (
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ //
|
||||||
|
+ // AmdSevDxe module is an apriori driver so it gets loaded between PEI
|
||||||
|
+ // and DXE phases and the SetVariable call will fail at the driver's
|
||||||
|
+ // entry point as the Variable DXE module is still not loaded yet.
|
||||||
|
+ // So we need to wait for an event notification which is signaled
|
||||||
|
+ // after the Variable DXE module is loaded, hence, using the
|
||||||
|
+ // EndOfDxe event notification to make this call.
|
||||||
|
+ //
|
||||||
|
+ // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
|
||||||
|
+ // The notification function sets the runtime variable indicating OVMF
|
||||||
|
+ // support for SEV live migration.
|
||||||
|
+ //
|
||||||
|
+ Status = gBS->CreateEventEx (
|
||||||
|
+ EVT_NOTIFY_SIGNAL,
|
||||||
|
+ TPL_CALLBACK,
|
||||||
|
+ AmdSevDxeOnEndOfDxe,
|
||||||
|
+ NULL,
|
||||||
|
+ &gEfiEndOfDxeEventGroupGuid,
|
||||||
|
+ &Event
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ DEBUG ((
|
||||||
|
+ DEBUG_ERROR,
|
||||||
|
+ "%a: CreateEventEx(): %r\n",
|
||||||
|
+ __FUNCTION__,
|
||||||
|
+ Status
|
||||||
|
+ ));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
|
||||||
|
index e7c7d526..dd1da527 100644
|
||||||
|
--- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
|
||||||
|
+++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf
|
||||||
|
@@ -57,3 +57,7 @@
|
||||||
|
|
||||||
|
[Pcd]
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
|
||||||
|
+
|
||||||
|
+[Guids]
|
||||||
|
+ gAmdSevMemEncryptGuid
|
||||||
|
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
|
||||||
|
diff --git a/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..62d22e79
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/OvmfPkg/Include/Guid/AmdSevMemEncryptLib.h
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+/** @file
|
||||||
|
+
|
||||||
|
+ AMD Memory Encryption GUID, define a new GUID for defining
|
||||||
|
+ new UEFI environment variables assocaiated with SEV Memory Encryption.
|
||||||
|
+
|
||||||
|
+ Copyright (c) 2021, AMD Inc. All rights reserved.<BR>
|
||||||
|
+
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#ifndef __AMD_SEV_MEMENCRYPT_LIB_H__
|
||||||
|
+#define __AMD_SEV_MEMENCRYPT_LIB_H__
|
||||||
|
+
|
||||||
|
+#define AMD_SEV_MEMENCRYPT_GUID \
|
||||||
|
+{0x0cf29b71, 0x9e51, 0x433a, {0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75}}
|
||||||
|
+
|
||||||
|
+extern EFI_GUID gAmdSevMemEncryptGuid;
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
|
||||||
|
index 34bca309..d50b1ae3 100644
|
||||||
|
--- a/OvmfPkg/OvmfPkg.dec
|
||||||
|
+++ b/OvmfPkg/OvmfPkg.dec
|
||||||
|
@@ -170,6 +170,7 @@
|
||||||
|
gUefiOvmfPkgTdxAcpiHobGuid = {0x6a0c5870, 0xd4ed, 0x44f4, {0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0x0c, 0x8d}}
|
||||||
|
gEfiNonCcFvGuid = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
|
||||||
|
gOvmfVariableGuid = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
|
||||||
|
+ gAmdSevMemEncryptGuid = {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
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
From fbdd6e4664e41eb299a797f1ab615d81b1bd958b Mon Sep 17 00:00:00 2001
|
||||||
|
From: hanliyang <hanliyang@hygon.cn>
|
||||||
|
Date: Mon, 17 Jan 2022 01:19:21 -0500
|
||||||
|
Subject: [PATCH 7/9] OvmfPkg/BaseMemcryptSevLib: Correct the calculation of
|
||||||
|
page range that notified to hypervisor
|
||||||
|
|
||||||
|
Correct the calculation of page range that notified to hypervisor.
|
||||||
|
|
||||||
|
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||||
|
---
|
||||||
|
.../Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||||
|
index 42e3b03f..69ada871 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c
|
||||||
|
@@ -999,9 +999,13 @@ SetMemoryEncDec (
|
||||||
|
// Notify Hypervisor on C-bit status
|
||||||
|
//
|
||||||
|
if (CBitChanged) {
|
||||||
|
+ UINTN StartPfn = OrigPhysicalAddress >> EFI_PAGE_SHIFT;
|
||||||
|
+ UINTN EndPfn = (OrigPhysicalAddress + OrigLength +
|
||||||
|
+ ((1 << EFI_PAGE_SHIFT) - 1)) >> EFI_PAGE_SHIFT;
|
||||||
|
+
|
||||||
|
Status = SetMemoryEncDecHypercall3 (
|
||||||
|
OrigPhysicalAddress,
|
||||||
|
- EFI_SIZE_TO_PAGES (OrigLength),
|
||||||
|
+ (EndPfn - StartPfn),
|
||||||
|
(Mode == SetCBit) ? TRUE : FALSE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
From 6b7bb04614be39e9903c602dd65ba18426f6a6f2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: hanliyang <hanliyang@hygon.cn>
|
||||||
|
Date: Sun, 19 Jun 2022 18:12:35 +0800
|
||||||
|
Subject: [PATCH 8/9] OvmfPkg/BaseMemEncryptLib: Return SUCCESS if not support
|
||||||
|
SEV live migration
|
||||||
|
|
||||||
|
Add this change to avoid trigger 'ASSERT_EFI_ERROR (Status = Unsupported)'
|
||||||
|
when QEMU doesn't support SEV live migration.
|
||||||
|
|
||||||
|
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||||
|
---
|
||||||
|
OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||||
|
index a64ff2a5..7b29582d 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/MemEncryptSevLib.c
|
||||||
|
@@ -168,10 +168,12 @@ SetMemoryEncDecHypercall3 (
|
||||||
|
UINTN Error;
|
||||||
|
UINTN EncryptState;
|
||||||
|
|
||||||
|
- Ret = RETURN_UNSUPPORTED;
|
||||||
|
+ //
|
||||||
|
+ // Return success if not support migration.
|
||||||
|
+ //
|
||||||
|
+ Ret = RETURN_SUCCESS;
|
||||||
|
|
||||||
|
if (MemEncryptSevLiveMigrationIsEnabled ()) {
|
||||||
|
- Ret = RETURN_SUCCESS;
|
||||||
|
//
|
||||||
|
// The encryption bit is set/clear on the smallest page size, hence
|
||||||
|
// use the 4k page size in MAP_GPA_RANGE hypercall below.
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
159
0076-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt-status.patch
Normal file
159
0076-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt-status.patch
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
From d9edefe3936aecbb9640a390cd990f1771e0dac2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xin Jiang <jiangxin@hygon.cn>
|
||||||
|
Date: Wed, 10 Jan 2024 17:34:57 +0800
|
||||||
|
Subject: [PATCH 9/9] OvmfPkg/BaseMemEncryptLib: Save memory encrypt status in
|
||||||
|
reserved memory
|
||||||
|
|
||||||
|
The MMIO routine of VC handler will get memory encrypt status to
|
||||||
|
validate MMIO address. MemEncryptSevGetEncryptionMask() will enable
|
||||||
|
interrupt while interrupt must be disabled during VC.
|
||||||
|
|
||||||
|
During DXE stage, VC routine as below:
|
||||||
|
CcExitHandleVc->MemEncryptSevGetAddressRangeState->
|
||||||
|
MemEncryptSevGetEncryptionMask->PcdGet64(PcdPteMemoryEncryptionAddressOrMask)
|
||||||
|
|
||||||
|
Unfortunately, PcdGet64() will enable interrupt in VC context.
|
||||||
|
|
||||||
|
Signed-off-by: Xin Jiang <jiangxin@hygon.cn>
|
||||||
|
---
|
||||||
|
OvmfPkg/AmdSev/AmdSevX64.fdf | 5 ++++-
|
||||||
|
.../Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 4 ++++
|
||||||
|
.../BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c | 9 ++-------
|
||||||
|
OvmfPkg/OvmfPkg.dec | 4 ++++
|
||||||
|
OvmfPkg/OvmfPkgX64.fdf | 5 ++++-
|
||||||
|
OvmfPkg/PlatformPei/AmdSev.c | 2 ++
|
||||||
|
OvmfPkg/PlatformPei/Csv.c | 6 ++++++
|
||||||
|
OvmfPkg/PlatformPei/PlatformPei.inf | 2 ++
|
||||||
|
8 files changed, 28 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf
|
||||||
|
index 714ab004..b0d9033f 100644
|
||||||
|
--- a/OvmfPkg/AmdSev/AmdSevX64.fdf
|
||||||
|
+++ b/OvmfPkg/AmdSev/AmdSevX64.fdf
|
||||||
|
@@ -80,7 +80,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGui
|
||||||
|
0x012000|0x001000
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize
|
||||||
|
|
||||||
|
-0x013000|0x00D000
|
||||||
|
+0x013000|0x001000
|
||||||
|
+gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||||
|
+
|
||||||
|
+0x014000|0x00C000
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
|
||||||
|
|
||||||
|
0x020000|0x0E0000
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||||
|
index 4d32fae6..6f2f69d0 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
|
||||||
|
@@ -61,3 +61,7 @@
|
||||||
|
[Pcd]
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
|
||||||
|
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr
|
||||||
|
+
|
||||||
|
+[FixedPcd]
|
||||||
|
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase
|
||||||
|
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||||
|
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||||
|
index d80ebe2f..a9d43237 100644
|
||||||
|
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||||
|
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
|
||||||
|
@@ -22,8 +22,6 @@
|
||||||
|
|
||||||
|
STATIC UINT64 mCurrentAttr = 0;
|
||||||
|
STATIC BOOLEAN mCurrentAttrRead = FALSE;
|
||||||
|
-STATIC UINT64 mSevEncryptionMask = 0;
|
||||||
|
-STATIC BOOLEAN mSevEncryptionMaskSaved = FALSE;
|
||||||
|
STATIC BOOLEAN mSevLiveMigrationStatus = FALSE;
|
||||||
|
STATIC BOOLEAN mSevLiveMigrationStatusChecked = FALSE;
|
||||||
|
|
||||||
|
@@ -193,10 +191,7 @@ MemEncryptSevGetEncryptionMask (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
- if (!mSevEncryptionMaskSaved) {
|
||||||
|
- mSevEncryptionMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);
|
||||||
|
- mSevEncryptionMaskSaved = TRUE;
|
||||||
|
- }
|
||||||
|
+ UINT64 *MemEncryptStatus = (UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase);
|
||||||
|
|
||||||
|
- return mSevEncryptionMask;
|
||||||
|
+ return *MemEncryptStatus;
|
||||||
|
}
|
||||||
|
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
|
||||||
|
index d50b1ae3..a6016d58 100644
|
||||||
|
--- a/OvmfPkg/OvmfPkg.dec
|
||||||
|
+++ b/OvmfPkg/OvmfPkg.dec
|
||||||
|
@@ -443,6 +443,10 @@
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|0|UINT32|0x72
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize|0|UINT32|0x73
|
||||||
|
|
||||||
|
+ ## the base address of memory encryption status.
|
||||||
|
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|0|UINT32|0x74
|
||||||
|
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize|0|UINT32|0x75
|
||||||
|
+
|
||||||
|
[PcdsDynamic, PcdsDynamicEx]
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
|
||||||
|
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
|
||||||
|
index b1cf0d99..a34b9f57 100644
|
||||||
|
--- a/OvmfPkg/OvmfPkgX64.fdf
|
||||||
|
+++ b/OvmfPkg/OvmfPkgX64.fdf
|
||||||
|
@@ -100,7 +100,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase|gUefiOvmfPkgTokenSpaceGui
|
||||||
|
0x011000|0x001000
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize
|
||||||
|
|
||||||
|
-0x012000|0x00E000
|
||||||
|
+0x012000|0x001000
|
||||||
|
+gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||||
|
+
|
||||||
|
+0x013000|0x00D000
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
|
||||||
|
|
||||||
|
0x020000|0x0E0000
|
||||||
|
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
|
||||||
|
index 553e841e..7c4ef899 100644
|
||||||
|
--- a/OvmfPkg/PlatformPei/AmdSev.c
|
||||||
|
+++ b/OvmfPkg/PlatformPei/AmdSev.c
|
||||||
|
@@ -379,6 +379,8 @@ AmdSevInitialize (
|
||||||
|
PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);
|
||||||
|
ASSERT_RETURN_ERROR (PcdStatus);
|
||||||
|
|
||||||
|
+ *(UINT64 *)(UINT64)FixedPcdGet32 (PcdMemEncrpytStatusBase) = EncryptionMask;
|
||||||
|
+
|
||||||
|
DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));
|
||||||
|
|
||||||
|
//
|
||||||
|
diff --git a/OvmfPkg/PlatformPei/Csv.c b/OvmfPkg/PlatformPei/Csv.c
|
||||||
|
index a52112d5..fe8c059b 100644
|
||||||
|
--- a/OvmfPkg/PlatformPei/Csv.c
|
||||||
|
+++ b/OvmfPkg/PlatformPei/Csv.c
|
||||||
|
@@ -33,6 +33,12 @@ CsvInitializeMemInfo (
|
||||||
|
UINT64 LowerMemorySize;
|
||||||
|
UINT64 UpperMemorySize;
|
||||||
|
|
||||||
|
+ BuildMemoryAllocationHob (
|
||||||
|
+ (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusBase),
|
||||||
|
+ (UINT64)(UINTN) FixedPcdGet32 (PcdMemEncrpytStatusSize),
|
||||||
|
+ EfiReservedMemoryType
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
if (!CsvIsEnabled ()) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
|
||||||
|
index 07de179f..c2d503fa 100644
|
||||||
|
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
|
||||||
|
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
|
||||||
|
@@ -137,6 +137,8 @@
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidSize
|
||||||
|
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase
|
||||||
|
+ gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize
|
||||||
|
|
||||||
|
[FeaturePcd]
|
||||||
|
gUefiOvmfPkgTokenSpaceGuid.PcdCsmEnable
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
218
0077-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
Normal file
218
0077-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
From ceb82e7d081399dd91cc6e0e8eabd5b7260afac0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adttil <2429917001@qq.com>
|
||||||
|
Date: Fri, 29 Nov 2024 08:35:27 +0800
|
||||||
|
Subject: [PATCH 1/3] VirtioDxe: add support of MMIO Bar for virtio devices
|
||||||
|
|
||||||
|
As some virtio devices support MMIO BAR, add support for
|
||||||
|
it in Virtio10Dxe and VirtioPciDeviceDXE.
|
||||||
|
|
||||||
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/Include/Protocol/VirtioDevice.h | 12 +++
|
||||||
|
.../VirtioMmioDeviceLib/VirtioMmioDevice.c | 1 +
|
||||||
|
OvmfPkg/Virtio10Dxe/Virtio10.c | 1 +
|
||||||
|
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 89 +++++++++++++++----
|
||||||
|
4 files changed, 85 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h b/OvmfPkg/Include/Protocol/VirtioDevice.h
|
||||||
|
index ad37f4e3..802b8970 100644
|
||||||
|
--- a/OvmfPkg/Include/Protocol/VirtioDevice.h
|
||||||
|
+++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
|
||||||
|
@@ -466,6 +466,16 @@ EFI_STATUS
|
||||||
|
IN VOID *Mapping
|
||||||
|
);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * Note: Zero virtio devices has BAR0 of type MMIO but not PIO which do not
|
||||||
|
+ * flow the virtio 0.95 spec due to hw limiation. We extend edk2 to support
|
||||||
|
+ * such variant.
|
||||||
|
+ */
|
||||||
|
+typedef enum {
|
||||||
|
+ VirtioCfgSpaceAcessIo = 0,
|
||||||
|
+ VirtioCfgSpaceAcessMem
|
||||||
|
+} VIRTIO_CFG_SPACE_ACCESS_MODE;
|
||||||
|
+
|
||||||
|
///
|
||||||
|
/// This protocol provides an abstraction over the VirtIo transport layer
|
||||||
|
///
|
||||||
|
@@ -482,6 +492,8 @@ struct _VIRTIO_DEVICE_PROTOCOL {
|
||||||
|
//
|
||||||
|
INT32 SubSystemDeviceId;
|
||||||
|
|
||||||
|
+ VIRTIO_CFG_SPACE_ACCESS_MODE CfgAccessMode;
|
||||||
|
+
|
||||||
|
VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures;
|
||||||
|
VIRTIO_SET_GUEST_FEATURES SetGuestFeatures;
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
||||||
|
index fac32422..a340711d 100644
|
||||||
|
--- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
||||||
|
+++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
STATIC CONST VIRTIO_DEVICE_PROTOCOL mMmioDeviceProtocolTemplate = {
|
||||||
|
0, // Revision
|
||||||
|
0, // SubSystemDeviceId
|
||||||
|
+ 0, // CfgAccessMode
|
||||||
|
VirtioMmioGetDeviceFeatures, // GetDeviceFeatures
|
||||||
|
VirtioMmioSetGuestFeatures, // SetGuestFeatures
|
||||||
|
VirtioMmioSetQueueAddress, // SetQueueAddress
|
||||||
|
diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c
|
||||||
|
index 970524f6..b968b016 100644
|
||||||
|
--- a/OvmfPkg/Virtio10Dxe/Virtio10.c
|
||||||
|
+++ b/OvmfPkg/Virtio10Dxe/Virtio10.c
|
||||||
|
@@ -954,6 +954,7 @@ Virtio10UnmapSharedBuffer (
|
||||||
|
STATIC CONST VIRTIO_DEVICE_PROTOCOL mVirtIoTemplate = {
|
||||||
|
VIRTIO_SPEC_REVISION (1, 0, 0),
|
||||||
|
0, // SubSystemDeviceId, filled in dynamically
|
||||||
|
+ 0, // CfgAccessMode
|
||||||
|
Virtio10GetDeviceFeatures,
|
||||||
|
Virtio10SetGuestFeatures,
|
||||||
|
Virtio10SetQueueAddress,
|
||||||
|
diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
||||||
|
index b4ac195b..61ff376d 100644
|
||||||
|
--- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
||||||
|
+++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = {
|
||||||
|
0, // Revision
|
||||||
|
0, // SubSystemDeviceId
|
||||||
|
+ 0, // CfgAccessMode
|
||||||
|
VirtioPciGetDeviceFeatures, // GetDeviceFeatures
|
||||||
|
VirtioPciSetGuestFeatures, // SetGuestFeatures
|
||||||
|
VirtioPciSetQueueAddress, // SetQueueAddress
|
||||||
|
@@ -117,14 +118,25 @@ VirtioPciIoRead (
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return PciIo->Io.Read (
|
||||||
|
- PciIo,
|
||||||
|
- Width,
|
||||||
|
- PCI_BAR_IDX0,
|
||||||
|
- FieldOffset,
|
||||||
|
- Count,
|
||||||
|
- Buffer
|
||||||
|
- );
|
||||||
|
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
|
||||||
|
+ return PciIo->Io.Read (
|
||||||
|
+ PciIo,
|
||||||
|
+ Width,
|
||||||
|
+ PCI_BAR_IDX0,
|
||||||
|
+ FieldOffset,
|
||||||
|
+ Count,
|
||||||
|
+ Buffer
|
||||||
|
+ );
|
||||||
|
+ } else {
|
||||||
|
+ return PciIo->Mem.Read (
|
||||||
|
+ PciIo,
|
||||||
|
+ Width,
|
||||||
|
+ PCI_BAR_IDX0,
|
||||||
|
+ FieldOffset,
|
||||||
|
+ Count,
|
||||||
|
+ Buffer
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -197,14 +209,25 @@ VirtioPciIoWrite (
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return PciIo->Io.Write (
|
||||||
|
- PciIo,
|
||||||
|
- Width,
|
||||||
|
- PCI_BAR_IDX0,
|
||||||
|
- FieldOffset,
|
||||||
|
- Count,
|
||||||
|
- &Value
|
||||||
|
- );
|
||||||
|
+ if (Dev->VirtioDevice.CfgAccessMode == VirtioCfgSpaceAcessIo) {
|
||||||
|
+ return PciIo->Io.Write (
|
||||||
|
+ PciIo,
|
||||||
|
+ Width,
|
||||||
|
+ PCI_BAR_IDX0,
|
||||||
|
+ FieldOffset,
|
||||||
|
+ Count,
|
||||||
|
+ &Value
|
||||||
|
+ );
|
||||||
|
+ } else {
|
||||||
|
+ return PciIo->Mem.Write (
|
||||||
|
+ PciIo,
|
||||||
|
+ Width,
|
||||||
|
+ PCI_BAR_IDX0,
|
||||||
|
+ FieldOffset,
|
||||||
|
+ Count,
|
||||||
|
+ &Value
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -332,6 +355,7 @@ VirtioPciInit (
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
PCI_TYPE00 Pci;
|
||||||
|
+ VOID *Resources;
|
||||||
|
|
||||||
|
ASSERT (Device != NULL);
|
||||||
|
PciIo = Device->PciIo;
|
||||||
|
@@ -373,6 +397,27 @@ VirtioPciInit (
|
||||||
|
Device->DeviceSpecificConfigurationOffset =
|
||||||
|
VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI;
|
||||||
|
|
||||||
|
+ Status = PciIo->GetBarAttributes(PciIo, PCI_BAR_IDX0, NULL, &Resources);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ return Status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (*(UINT8 *)Resources == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) {
|
||||||
|
+ EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
|
||||||
|
+
|
||||||
|
+ Descriptor = Resources;
|
||||||
|
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
|
||||||
|
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessMem;
|
||||||
|
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio MMIO BAR used.\n", __FUNCTION__));
|
||||||
|
+ } else {
|
||||||
|
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
|
||||||
|
+ DEBUG ((DEBUG_INFO, "%a: Legacy Virtio IO BAR used.\n", __FUNCTION__));
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ DEBUG ((DEBUG_WARN, "%a: Cannot determine BAR0 type, assume IO.\n", __FUNCTION__));
|
||||||
|
+ Device->VirtioDevice.CfgAccessMode = VirtioCfgSpaceAcessIo;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -434,6 +479,7 @@ VirtioPciDeviceBindingStart (
|
||||||
|
{
|
||||||
|
VIRTIO_PCI_DEVICE *Device;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
+ UINT64 Attributes;
|
||||||
|
|
||||||
|
Device = (VIRTIO_PCI_DEVICE *)AllocateZeroPool (sizeof *Device);
|
||||||
|
if (Device == NULL) {
|
||||||
|
@@ -473,11 +519,18 @@ VirtioPciDeviceBindingStart (
|
||||||
|
goto ClosePciIo;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ Status = Device->PciIo->Attributes (Device->PciIo,
|
||||||
|
+ EfiPciIoAttributeOperationSupported,
|
||||||
|
+ 0, &Attributes);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ goto ClosePciIo;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Attributes &= (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO);
|
||||||
|
Status = Device->PciIo->Attributes (
|
||||||
|
Device->PciIo,
|
||||||
|
EfiPciIoAttributeOperationEnable,
|
||||||
|
- (EFI_PCI_IO_ATTRIBUTE_IO |
|
||||||
|
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
|
||||||
|
+ Attributes | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
123
0078-Virtio-wait-virtio-device-reset-done.patch
Normal file
123
0078-Virtio-wait-virtio-device-reset-done.patch
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
From 05de598734e741c596394bfbe42b1ab7af8316e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adttil <2429917001@qq.com>
|
||||||
|
Date: Fri, 29 Nov 2024 08:46:00 +0800
|
||||||
|
Subject: [PATCH 2/3] Virtio: wait virtio device reset done.
|
||||||
|
|
||||||
|
The Virtio 1.0 driver performs subsequent negotiation operations
|
||||||
|
only after the device reset operation is complete.
|
||||||
|
|
||||||
|
Implement this in the VirtioScsiDxe and VirtioBlkDxe.
|
||||||
|
|
||||||
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
||||||
|
---
|
||||||
|
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 21 +++++++++++++++++++++
|
||||||
|
OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 21 +++++++++++++++++++++
|
||||||
|
2 files changed, 42 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||||
|
index 74ed52f9..eed56994 100644
|
||||||
|
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||||
|
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||||
|
@@ -28,6 +28,9 @@
|
||||||
|
|
||||||
|
#include "VirtioBlk.h"
|
||||||
|
|
||||||
|
+#define MAX_RETRY_TIMES 1000
|
||||||
|
+#define DEVICE_WAIT_INTVL 1000
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
|
||||||
|
Convenience macros to read and write region 0 IO space elements of the
|
||||||
|
@@ -721,6 +724,10 @@ VirtioBlkInit (
|
||||||
|
UINT32 OptIoSize;
|
||||||
|
UINT16 QueueSize;
|
||||||
|
UINT64 RingBaseShift;
|
||||||
|
+ UINT8 DevStat;
|
||||||
|
+ UINT16 RetryTimes;
|
||||||
|
+
|
||||||
|
+ RetryTimes = MAX_RETRY_TIMES;
|
||||||
|
|
||||||
|
PhysicalBlockExp = 0;
|
||||||
|
AlignmentOffset = 0;
|
||||||
|
@@ -735,12 +742,26 @@ VirtioBlkInit (
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||||
|
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ RetryTimes--;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
|
||||||
|
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||||
|
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ RetryTimes--;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
|
||||||
|
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
|
||||||
|
index 3705f5fc..580fe731 100644
|
||||||
|
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
|
||||||
|
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
|
||||||
|
@@ -43,6 +43,9 @@
|
||||||
|
|
||||||
|
#include "VirtioScsi.h"
|
||||||
|
|
||||||
|
+#define MAX_RETRY_TIMES 1000
|
||||||
|
+#define DEVICE_WAIT_INTVL 1000
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
|
||||||
|
Convenience macros to read and write configuration elements of the
|
||||||
|
@@ -932,6 +935,10 @@ VirtioScsiInit (
|
||||||
|
UINT16 MaxChannel; // for validation only
|
||||||
|
UINT32 NumQueues; // for validation only
|
||||||
|
UINT16 QueueSize;
|
||||||
|
+ UINT8 DevStat;
|
||||||
|
+ UINT16 RetryTimes;
|
||||||
|
+
|
||||||
|
+ RetryTimes = MAX_RETRY_TIMES;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
|
||||||
|
@@ -942,12 +949,26 @@ VirtioScsiInit (
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||||
|
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ RetryTimes--;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
|
||||||
|
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ while (DevStat != NextDevStat && RetryTimes) {
|
||||||
|
+ gBS->Stall(DEVICE_WAIT_INTVL);
|
||||||
|
+ Status = Dev->VirtIo->GetDeviceStatus (Dev->VirtIo, &DevStat);
|
||||||
|
+ RetryTimes--;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
|
||||||
|
Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
250
0079-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
Normal file
250
0079-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
From 734457162d02f6b4d66b8eb82da0717765fceebe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adttil <2429917001@qq.com>
|
||||||
|
Date: Fri, 29 Nov 2024 09:04:13 +0800
|
||||||
|
Subject: [PATCH 3/3] VirtioBlk: split large IO according to segment_size_max
|
||||||
|
|
||||||
|
When the VirtioBlk device is initialized, the value of SegmentSizeMax
|
||||||
|
is obtained based on the feature capability. Then delivere the requests
|
||||||
|
based on the value of SegmentSizeMax.
|
||||||
|
|
||||||
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
||||||
|
---
|
||||||
|
MdePkg/Include/Protocol/BlockIo.h | 10 ++
|
||||||
|
OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 148 +++++++++++++++++++++---------
|
||||||
|
2 files changed, 117 insertions(+), 41 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/MdePkg/Include/Protocol/BlockIo.h b/MdePkg/Include/Protocol/BlockIo.h
|
||||||
|
index ac9adf7a..ac5e1c2a 100644
|
||||||
|
--- a/MdePkg/Include/Protocol/BlockIo.h
|
||||||
|
+++ b/MdePkg/Include/Protocol/BlockIo.h
|
||||||
|
@@ -197,6 +197,16 @@ typedef struct {
|
||||||
|
/// granularity as a number of logical blocks.
|
||||||
|
///
|
||||||
|
UINT32 OptimalTransferLengthGranularity;
|
||||||
|
+
|
||||||
|
+ ///
|
||||||
|
+ /// Maximum size of any single segment
|
||||||
|
+ ///
|
||||||
|
+ UINT32 MaxSegmentSize;
|
||||||
|
+
|
||||||
|
+ ///
|
||||||
|
+ /// Maximum number of segments in a request
|
||||||
|
+ ///
|
||||||
|
+ UINT32 MaxSegments;
|
||||||
|
} EFI_BLOCK_IO_MEDIA;
|
||||||
|
|
||||||
|
#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000
|
||||||
|
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||||
|
index eed56994..6d7c7aef 100644
|
||||||
|
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||||
|
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
|
||||||
|
@@ -31,6 +31,8 @@
|
||||||
|
#define MAX_RETRY_TIMES 1000
|
||||||
|
#define DEVICE_WAIT_INTVL 1000
|
||||||
|
|
||||||
|
+#define DEFAULT_MAX_SEGMENTS 32
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
|
||||||
|
Convenience macros to read and write region 0 IO space elements of the
|
||||||
|
@@ -460,6 +462,68 @@ FreeHostStatusBuffer:
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
+STATIC
|
||||||
|
+EFI_STATUS
|
||||||
|
+EFIAPI
|
||||||
|
+VirtioBlkReadWriteBlocks (
|
||||||
|
+ IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
|
+ IN UINT32 MediaId,
|
||||||
|
+ IN EFI_LBA Lba,
|
||||||
|
+ IN UINTN BufferSize,
|
||||||
|
+ IN OUT VOID *Buffer,
|
||||||
|
+ IN BOOLEAN RequestIsWrite
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ VBLK_DEV *Dev;
|
||||||
|
+ EFI_STATUS Status;
|
||||||
|
+ UINT32 SizeMax;
|
||||||
|
+
|
||||||
|
+ if (BufferSize == 0) {
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
|
||||||
|
+ Status = VerifyReadWriteRequest (
|
||||||
|
+ &Dev->BlockIoMedia,
|
||||||
|
+ Lba,
|
||||||
|
+ BufferSize,
|
||||||
|
+ RequestIsWrite
|
||||||
|
+ );
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ return Status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SizeMax = Dev->BlockIoMedia.MaxSegmentSize;
|
||||||
|
+ while (BufferSize >= SizeMax) {
|
||||||
|
+ Status = SynchronousRequest (
|
||||||
|
+ Dev,
|
||||||
|
+ Lba,
|
||||||
|
+ SizeMax,
|
||||||
|
+ Buffer,
|
||||||
|
+ RequestIsWrite
|
||||||
|
+ );
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ return Status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Lba += SizeMax / Dev->BlockIoMedia.BlockSize;
|
||||||
|
+ BufferSize -= SizeMax;
|
||||||
|
+ Buffer = (CHAR8 *)Buffer + SizeMax;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (BufferSize == 0) {
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return SynchronousRequest (
|
||||||
|
+ Dev,
|
||||||
|
+ Lba,
|
||||||
|
+ BufferSize,
|
||||||
|
+ Buffer,
|
||||||
|
+ RequestIsWrite
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
|
||||||
|
ReadBlocks() operation for virtio-blk.
|
||||||
|
@@ -487,30 +551,13 @@ VirtioBlkReadBlocks (
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
- VBLK_DEV *Dev;
|
||||||
|
- EFI_STATUS Status;
|
||||||
|
-
|
||||||
|
- if (BufferSize == 0) {
|
||||||
|
- return EFI_SUCCESS;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
|
||||||
|
- Status = VerifyReadWriteRequest (
|
||||||
|
- &Dev->BlockIoMedia,
|
||||||
|
- Lba,
|
||||||
|
- BufferSize,
|
||||||
|
- FALSE // RequestIsWrite
|
||||||
|
- );
|
||||||
|
- if (EFI_ERROR (Status)) {
|
||||||
|
- return Status;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return SynchronousRequest (
|
||||||
|
- Dev,
|
||||||
|
+ return VirtioBlkReadWriteBlocks(
|
||||||
|
+ This,
|
||||||
|
+ MediaId,
|
||||||
|
Lba,
|
||||||
|
BufferSize,
|
||||||
|
Buffer,
|
||||||
|
- FALSE // RequestIsWrite
|
||||||
|
+ FALSE // RequestIsRead
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -541,26 +588,9 @@ VirtioBlkWriteBlocks (
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
- VBLK_DEV *Dev;
|
||||||
|
- EFI_STATUS Status;
|
||||||
|
-
|
||||||
|
- if (BufferSize == 0) {
|
||||||
|
- return EFI_SUCCESS;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
|
||||||
|
- Status = VerifyReadWriteRequest (
|
||||||
|
- &Dev->BlockIoMedia,
|
||||||
|
- Lba,
|
||||||
|
- BufferSize,
|
||||||
|
- TRUE // RequestIsWrite
|
||||||
|
- );
|
||||||
|
- if (EFI_ERROR (Status)) {
|
||||||
|
- return Status;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return SynchronousRequest (
|
||||||
|
- Dev,
|
||||||
|
+ return VirtioBlkReadWriteBlocks(
|
||||||
|
+ This,
|
||||||
|
+ MediaId,
|
||||||
|
Lba,
|
||||||
|
BufferSize,
|
||||||
|
Buffer,
|
||||||
|
@@ -716,6 +746,8 @@ VirtioBlkInit (
|
||||||
|
UINT8 NextDevStat;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
+ UINT32 MaxSegmentSize;
|
||||||
|
+ UINT32 MaxSegments;
|
||||||
|
UINT64 Features;
|
||||||
|
UINT64 NumSectors;
|
||||||
|
UINT32 BlockSize;
|
||||||
|
@@ -814,6 +846,36 @@ VirtioBlkInit (
|
||||||
|
BlockSize = 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (Features & VIRTIO_BLK_F_SIZE_MAX) {
|
||||||
|
+ Status = VIRTIO_CFG_READ (Dev, SizeMax, &MaxSegmentSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ goto Failed;
|
||||||
|
+ }
|
||||||
|
+ if (MaxSegmentSize == 0) {
|
||||||
|
+ //
|
||||||
|
+ // We need at least one 4KB page.
|
||||||
|
+ //
|
||||||
|
+ MaxSegmentSize = SIZE_4KB;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ MaxSegmentSize = SIZE_512KB;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (Features & VIRTIO_BLK_F_SEG_MAX) {
|
||||||
|
+ Status = VIRTIO_CFG_READ (Dev, SegMax, &MaxSegments);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ goto Failed;
|
||||||
|
+ }
|
||||||
|
+ if (MaxSegments == 0) {
|
||||||
|
+ //
|
||||||
|
+ // We need at least one SG element, whatever they say.
|
||||||
|
+ //
|
||||||
|
+ MaxSegments = 1;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ MaxSegments = DEFAULT_MAX_SEGMENTS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (Features & VIRTIO_BLK_F_TOPOLOGY) {
|
||||||
|
Status = VIRTIO_CFG_READ (
|
||||||
|
Dev,
|
||||||
|
@@ -955,6 +1017,8 @@ VirtioBlkInit (
|
||||||
|
Dev->BlockIoMedia.ReadOnly = (BOOLEAN)((Features & VIRTIO_BLK_F_RO) != 0);
|
||||||
|
Dev->BlockIoMedia.WriteCaching = (BOOLEAN)((Features & VIRTIO_BLK_F_FLUSH) != 0);
|
||||||
|
Dev->BlockIoMedia.BlockSize = BlockSize;
|
||||||
|
+ Dev->BlockIoMedia.MaxSegments = MaxSegments;
|
||||||
|
+ Dev->BlockIoMedia.MaxSegmentSize = MaxSegmentSize;
|
||||||
|
Dev->BlockIoMedia.IoAlign = 0;
|
||||||
|
Dev->BlockIoMedia.LastBlock = DivU64x32 (
|
||||||
|
NumSectors,
|
||||||
|
@@ -968,6 +1032,8 @@ VirtioBlkInit (
|
||||||
|
Dev->BlockIoMedia.BlockSize,
|
||||||
|
Dev->BlockIoMedia.LastBlock + 1
|
||||||
|
));
|
||||||
|
+ DEBUG ((DEBUG_INFO, "%a: MaxSegments=0x%x[B] MaxSegmentSize=0x%x[B]\n",
|
||||||
|
+ __FUNCTION__, Dev->BlockIoMedia.MaxSegments, Dev->BlockIoMedia.MaxSegmentSize));
|
||||||
|
|
||||||
|
if (Features & VIRTIO_BLK_F_TOPOLOGY) {
|
||||||
|
Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
25
edk2.spec
25
edk2.spec
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
Name: edk2
|
Name: edk2
|
||||||
Version: %{stable_date}
|
Version: %{stable_date}
|
||||||
Release: 14
|
Release: 16
|
||||||
Summary: EFI Development Kit II
|
Summary: EFI Development Kit II
|
||||||
License: BSD-2-Clause-Patent and OpenSSL and MIT
|
License: BSD-2-Clause-Patent and OpenSSL and MIT
|
||||||
URL: https://github.com/tianocore/edk2
|
URL: https://github.com/tianocore/edk2
|
||||||
@ -110,6 +110,23 @@ patch65: 0065-OvmfPkg-IoMmuDxe-Add-CsvIoMmu-protocol.patch
|
|||||||
patch66: 0066-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-guest.patch
|
patch66: 0066-OvmfPkg-Reserve-a-CPUID-table-page-for-CSV-guest.patch
|
||||||
patch67: 0067-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch
|
patch67: 0067-OvmfPkg-Use-classic-mmio-window-for-CSV-guest.patch
|
||||||
|
|
||||||
|
# Support live migrate Hygon CSV/CSV2/CSV3 guest
|
||||||
|
patch68: 0068-OvmfPkg-BaseMemEncryptLib-Detect-SEV-live-migration-.patch
|
||||||
|
patch69: 0069-OvmfPkg-BaseMemEncryptLib-Hypercall-API-for-page-enc.patch
|
||||||
|
patch70: 0070-OvmfPkg-BaseMemEncryptLib-Invoke-page-encryption-sta.patch
|
||||||
|
patch71: 0071-OvmfPkg-VmgExitLib-Encryption-state-change-hypercall.patch
|
||||||
|
patch72: 0072-OvmfPkg-PlatformPei-Mark-SEC-GHCB-page-as-unencrypte.patch
|
||||||
|
patch73: 0073-OvmfPkg-AmdSevDxe-Add-support-for-SEV-live-migration.patch
|
||||||
|
patch74: 0074-OvmfPkg-BaseMemcryptSevLib-Correct-the-calculation-o.patch
|
||||||
|
patch75: 0075-OvmfPkg-BaseMemEncryptLib-Return-SUCCESS-if-not-supp.patch
|
||||||
|
# Fix nesting #VC in mmio check
|
||||||
|
patch76: 0076-OvmfPkg-BaseMemEncryptLib-Save-memory-encrypt-status.patch
|
||||||
|
|
||||||
|
# Support vdpa blk/scsi device boot
|
||||||
|
patch77: 0077-VirtioDxe-add-support-of-MMIO-Bar-for-virtio-devices.patch
|
||||||
|
patch78: 0078-Virtio-wait-virtio-device-reset-done.patch
|
||||||
|
patch79: 0079-VirtioBlk-split-large-IO-according-to-segment_size_m.patch
|
||||||
|
|
||||||
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
|
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -379,6 +396,12 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Nov 29 2024 adttil<2429917001@qq.com> - 202308-16
|
||||||
|
- vdpa: support vdpa blk/scsi device boot
|
||||||
|
|
||||||
|
* Wed Oct 23 2024 hanliyang<hanliyang@hygon.cn> - 202308-15
|
||||||
|
- Add support for live migration of Hygon CSV1/2/3 guests, fix nesting #VC
|
||||||
|
|
||||||
* Tue Nov 12 2024 hanliyang<hanliyang@hygon.cn> - 202308-14
|
* Tue Nov 12 2024 hanliyang<hanliyang@hygon.cn> - 202308-14
|
||||||
- Add support for running in Hygon CSV3 guest
|
- Add support for running in Hygon CSV3 guest
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user