summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OvmfPkg/Library/VmgExitLib/VmgExitLib.c26
-rw-r--r--OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c5
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c5
-rw-r--r--UefiCpuPkg/Include/Library/VmgExitLib.h14
-rw-r--r--UefiCpuPkg/Library/MpInitLib/DxeMpLib.c5
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c7
-rw-r--r--UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c18
7 files changed, 55 insertions, 25 deletions
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
index 0540df8a04..bc5cd61d75 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c
@@ -132,15 +132,27 @@ VmgExit (
Performs the necessary steps in preparation for invoking VMGEXIT. Must be
called before setting any fields within the GHCB.
- @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] InterruptState A pointer to hold the current interrupt
+ state, used for restoring in VmgDone ()
**/
VOID
EFIAPI
VmgInit (
- IN OUT GHCB *Ghcb
+ IN OUT GHCB *Ghcb,
+ IN OUT BOOLEAN *InterruptState
)
{
+ //
+ // Be sure that an interrupt can't cause a #VC while the GHCB is
+ // being used.
+ //
+ *InterruptState = GetInterruptState ();
+ if (*InterruptState) {
+ DisableInterrupts ();
+ }
+
SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0);
}
@@ -150,15 +162,21 @@ VmgInit (
Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
called after obtaining needed fields within the GHCB.
- @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] Ghcb A pointer to the GHCB
+ @param[in] InterruptState An indicator to conditionally (re)enable
+ interrupts
**/
VOID
EFIAPI
VmgDone (
- IN OUT GHCB *Ghcb
+ IN OUT GHCB *Ghcb,
+ IN BOOLEAN InterruptState
)
{
+ if (InterruptState) {
+ EnableInterrupts ();
+ }
}
/**
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
index 9bf9d16017..1671db3a01 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c
@@ -1568,6 +1568,7 @@ VmgExitHandleVc (
SEV_ES_INSTRUCTION_DATA InstructionData;
UINT64 ExitCode, Status;
EFI_STATUS VcRet;
+ BOOLEAN InterruptState;
VcRet = EFI_SUCCESS;
@@ -1578,7 +1579,7 @@ VmgExitHandleVc (
Regs = SystemContext.SystemContextX64;
Ghcb = Msr.Ghcb;
- VmgInit (Ghcb);
+ VmgInit (Ghcb, &InterruptState);
ExitCode = Regs->ExceptionData;
switch (ExitCode) {
@@ -1662,7 +1663,7 @@ VmgExitHandleVc (
VcRet = EFI_PROTOCOL_ERROR;
}
- VmgDone (Ghcb);
+ VmgDone (Ghcb, InterruptState);
return VcRet;
}
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
index f9b21b5413..1b0742967f 100644
--- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c
@@ -52,6 +52,7 @@ QemuFlashPtrWrite (
if (MemEncryptSevEsIsEnabled ()) {
MSR_SEV_ES_GHCB_REGISTER Msr;
GHCB *Ghcb;
+ BOOLEAN InterruptState;
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
Ghcb = Msr.Ghcb;
@@ -63,12 +64,12 @@ QemuFlashPtrWrite (
// #VC exception. Instead, use the the VMGEXIT MMIO write support directly
// to perform the update.
//
- VmgInit (Ghcb);
+ VmgInit (Ghcb, &InterruptState);
Ghcb->SharedBuffer[0] = Value;
Ghcb->SaveArea.SwScratch = (UINT64) (UINTN) Ghcb->SharedBuffer;
VmgSetOffsetValid (Ghcb, GhcbSwScratch);
VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, (UINT64) (UINTN) Ptr, 1);
- VmgDone (Ghcb);
+ VmgDone (Ghcb, InterruptState);
} else {
*Ptr = Value;
}
diff --git a/UefiCpuPkg/Include/Library/VmgExitLib.h b/UefiCpuPkg/Include/Library/VmgExitLib.h
index 07e8af6450..061948cf84 100644
--- a/UefiCpuPkg/Include/Library/VmgExitLib.h
+++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
@@ -50,13 +50,16 @@ VmgExit (
Performs the necessary steps in preparation for invoking VMGEXIT. Must be
called before setting any fields within the GHCB.
- @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] InterruptState A pointer to hold the current interrupt
+ state, used for restoring in VmgDone ()
**/
VOID
EFIAPI
VmgInit (
- IN OUT GHCB *Ghcb
+ IN OUT GHCB *Ghcb,
+ IN OUT BOOLEAN *InterruptState
);
/**
@@ -65,13 +68,16 @@ VmgInit (
Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
called after obtaining needed fields within the GHCB.
- @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] Ghcb A pointer to the GHCB
+ @param[in] InterruptState An indicator to conditionally (re)enable
+ interrupts
**/
VOID
EFIAPI
VmgDone (
- IN OUT GHCB *Ghcb
+ IN OUT GHCB *Ghcb,
+ IN BOOLEAN InterruptState
);
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
index 2c00d72dde..7839c24976 100644
--- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c
@@ -171,6 +171,7 @@ GetSevEsAPMemory (
EFI_PHYSICAL_ADDRESS StartAddress;
MSR_SEV_ES_GHCB_REGISTER Msr;
GHCB *Ghcb;
+ BOOLEAN InterruptState;
//
// Allocate 1 page for AP jump table page
@@ -192,9 +193,9 @@ GetSevEsAPMemory (
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
Ghcb = Msr.Ghcb;
- VmgInit (Ghcb);
+ VmgInit (Ghcb, &InterruptState);
VmgExit (Ghcb, SVM_EXIT_AP_JUMP_TABLE, 0, (UINT64) (UINTN) StartAddress);
- VmgDone (Ghcb);
+ VmgDone (Ghcb, InterruptState);
return (UINTN) StartAddress;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 6d977d45bc..1f47ff3f73 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -884,6 +884,7 @@ ApWakeupFunction (
GHCB *Ghcb;
UINT64 Status;
BOOLEAN DoDecrement;
+ BOOLEAN InterruptState;
DoDecrement = (BOOLEAN) (CpuMpData->InitFlag == ApInitConfig);
@@ -891,7 +892,7 @@ ApWakeupFunction (
Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);
Ghcb = Msr.Ghcb;
- VmgInit (Ghcb);
+ VmgInit (Ghcb, &InterruptState);
if (DoDecrement) {
DoDecrement = FALSE;
@@ -905,11 +906,11 @@ ApWakeupFunction (
Status = VmgExit (Ghcb, SVM_EXIT_AP_RESET_HOLD, 0, 0);
if ((Status == 0) && (Ghcb->SaveArea.SwExitInfo2 != 0)) {
- VmgDone (Ghcb);
+ VmgDone (Ghcb, InterruptState);
break;
}
- VmgDone (Ghcb);
+ VmgDone (Ghcb, InterruptState);
}
//
diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
index b47e282aff..89b065cb3f 100644
--- a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
+++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
@@ -57,15 +57,16 @@ VmgExit (
Performs the necessary steps in preparation for invoking VMGEXIT. Must be
called before setting any fields within the GHCB.
- The base library function does nothing.
-
- @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] InterruptState A pointer to hold the current interrupt
+ state, used for restoring in VmgDone ()
**/
VOID
EFIAPI
VmgInit (
- IN OUT GHCB *Ghcb
+ IN OUT GHCB *Ghcb,
+ IN OUT BOOLEAN *InterruptState
)
{
}
@@ -76,15 +77,16 @@ VmgInit (
Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
called after obtaining needed fields within the GHCB.
- The base library function does nothing.
-
- @param[in, out] Ghcb A pointer to the GHCB
+ @param[in, out] Ghcb A pointer to the GHCB
+ @param[in] InterruptState An indicator to conditionally (re)enable
+ interrupts
**/
VOID
EFIAPI
VmgDone (
- IN OUT GHCB *Ghcb
+ IN OUT GHCB *Ghcb,
+ IN BOOLEAN InterruptState
)
{
}