summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2024-03-08 07:31:11 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-04-17 18:30:03 +0000
commit069f9911a35c6191ea0cace0b5b5c8061e9b7720 (patch)
tree41ee1b09281339f4e37243174c8ffc7a98ee49f7
parent2b330b57dbe8014c5fa9f10d4cf4ae5923e3b143 (diff)
downloadedk2-069f9911a35c6191ea0cace0b5b5c8061e9b7720.tar.gz
edk2-069f9911a35c6191ea0cace0b5b5c8061e9b7720.tar.bz2
edk2-069f9911a35c6191ea0cace0b5b5c8061e9b7720.zip
OvmfPkg/BaseMemEncryptSevLib: Maximize Page State Change efficiency
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4654 When building the Page State Change entries for a range of memory, it can happen that multiple calls to BuildPageStateBuffer() need to be made. If the size of the input work area passed to BuildPageStateBuffer() exceeds the number of entries that can be passed to the hypervisor using the GHCB shared buffer, the Page State Change VMGEXIT support will issue multiple VMGEXITs to process all entries in the buffer. However, it could be that the final VMGEXIT for each round of Page State Changes is only for a small number of entries and subsequent VMGEXITs may still be issued to handle the full range of memory requested. To maximize the number of entries processed during the Page State Change VMGEXIT, limit BuildPageStateBuffer() to not build entries that exceed the maximum number of entries that can be handled in a single Page State Change VMGEXIT. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Michael Roth <michael.roth@amd.com> Cc: Min Xu <min.m.xu@intel.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
index bcc0798d6b..f1883239a6 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c
@@ -145,6 +145,7 @@ BuildPageStateBuffer (
UINTN RmpPageSize;
UINTN Index;
UINTN IndexMax;
+ UINTN PscIndexMax;
// Clear the page state structure
SetMem (Info, InfoSize, 0);
@@ -154,6 +155,16 @@ BuildPageStateBuffer (
NextAddress = EndAddress;
//
+ // Make the use of the work area as efficient as possible relative to
+ // exiting from the guest to the hypervisor. Maximize the number of entries
+ // that can be processed per exit.
+ //
+ PscIndexMax = (IndexMax / SNP_PAGE_STATE_MAX_ENTRY) * SNP_PAGE_STATE_MAX_ENTRY;
+ if (PscIndexMax > 0) {
+ IndexMax = MIN (IndexMax, PscIndexMax);
+ }
+
+ //
// Populate the page state entry structure
//
while ((BaseAddress < EndAddress) && (Index < IndexMax)) {