From a13967f2a31c6bacbb2410731c439b1cf5a5e474 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Fri, 6 Nov 2020 11:53:05 -0600 Subject: [PATCH] OvmfPkg/VmgExitLib: Implement new VmgExitLib interfaces BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3008 The VmgExitLib library added two new interfaces, VmgSetOffsetValid() and VmgIsOffsetValid(), that must now be implemented in the OvmfPkg version of the library. Implement VmgSetOffsetValid() and VmgIsOffsetValid() and update existing code, that is directly accessing ValidBitmap, to use the new interfaces. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Tom Lendacky Cc: Brijesh Singh Reviewed-by: Laszlo Ersek Signed-off-by: Tom Lendacky Message-Id: <939e9dc375e6085bc67942fe9a00ecd4c6b77ecf.1604685192.git.thomas.lendacky@amd.com> --- OvmfPkg/Library/VmgExitLib/VmgExitLib.c | 54 ++++++++ OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 118 +++++------------- 2 files changed, 85 insertions(+), 87 deletions(-) diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c index 53040cc6f6..21f68b19c9 100644 --- a/OvmfPkg/Library/VmgExitLib/VmgExitLib.c +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.c @@ -157,3 +157,57 @@ VmgDone ( { } +/** + Marks a field at the specified offset as valid in the GHCB. + + The ValidBitmap area represents the areas of the GHCB that have been marked + valid. Set the bit in ValidBitmap for the input offset. + + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block + @param[in] Offset Qword offset in the GHCB to mark valid + +**/ +VOID +EFIAPI +VmgSetOffsetValid ( + IN OUT GHCB *Ghcb, + IN GHCB_REGISTER Offset + ) +{ + UINT32 OffsetIndex; + UINT32 OffsetBit; + + OffsetIndex = Offset / 8; + OffsetBit = Offset % 8; + + Ghcb->SaveArea.ValidBitmap[OffsetIndex] |= (1 << OffsetBit); +} + +/** + Checks if a specified offset is valid in the GHCB. + + The ValidBitmap area represents the areas of the GHCB that have been marked + valid. Return whether the bit in the ValidBitmap is set for the input offset. + + @param[in] Ghcb A pointer to the GHCB + @param[in] Offset Qword offset in the GHCB to mark valid + + @retval TRUE Offset is marked valid in the GHCB + @retval FALSE Offset is not marked valid in the GHCB + +**/ +BOOLEAN +EFIAPI +VmgIsOffsetValid ( + IN GHCB *Ghcb, + IN GHCB_REGISTER Offset + ) +{ + UINT32 OffsetIndex; + UINT32 OffsetBit; + + OffsetIndex = Offset / 8; + OffsetBit = Offset % 8; + + return ((Ghcb->SaveArea.ValidBitmap[OffsetIndex] & (1 << OffsetBit)) != 0); +} diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c index 8e42b305e8..7d14341d59 100644 --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c @@ -135,62 +135,6 @@ typedef struct { } SEV_ES_PER_CPU_DATA; -/** - Checks the GHCB to determine if the specified register has been marked valid. - - The ValidBitmap area represents the areas of the GHCB that have been marked - valid. Return an indication of whether the area of the GHCB that holds the - specified register has been marked valid. - - @param[in] Ghcb Pointer to the Guest-Hypervisor Communication Block - @param[in] Reg Offset in the GHCB of the register to check - - @retval TRUE Register has been marked vald in the GHCB - @retval FALSE Register has not been marked valid in the GHCB - -**/ -STATIC -BOOLEAN -GhcbIsRegValid ( - IN GHCB *Ghcb, - IN GHCB_REGISTER Reg - ) -{ - UINT32 RegIndex; - UINT32 RegBit; - - RegIndex = Reg / 8; - RegBit = Reg & 0x07; - - return ((Ghcb->SaveArea.ValidBitmap[RegIndex] & (1 << RegBit)) != 0); -} - -/** - Marks a register as valid in the GHCB. - - The ValidBitmap area represents the areas of the GHCB that have been marked - valid. Set the area of the GHCB that holds the specified register as valid. - - @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block - @param[in] Reg Offset in the GHCB of the register to mark valid - -**/ -STATIC -VOID -GhcbSetRegValid ( - IN OUT GHCB *Ghcb, - IN GHCB_REGISTER Reg - ) -{ - UINT32 RegIndex; - UINT32 RegBit; - - RegIndex = Reg / 8; - RegBit = Reg & 0x07; - - Ghcb->SaveArea.ValidBitmap[RegIndex] |= (1 << RegBit); -} - /** Return a pointer to the contents of the specified register. @@ -891,9 +835,9 @@ MwaitExit ( DecodeModRm (Regs, InstructionData); Ghcb->SaveArea.Rax = Regs->Rax; - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Ghcb->SaveArea.Rcx = Regs->Rcx; - GhcbSetRegValid (Ghcb, GhcbRcx); + VmgSetOffsetValid (Ghcb, GhcbRcx); return VmgExit (Ghcb, SVM_EXIT_MWAIT, 0, 0); } @@ -923,11 +867,11 @@ MonitorExit ( DecodeModRm (Regs, InstructionData); Ghcb->SaveArea.Rax = Regs->Rax; // Identity mapped, so VA = PA - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Ghcb->SaveArea.Rcx = Regs->Rcx; - GhcbSetRegValid (Ghcb, GhcbRcx); + VmgSetOffsetValid (Ghcb, GhcbRcx); Ghcb->SaveArea.Rdx = Regs->Rdx; - GhcbSetRegValid (Ghcb, GhcbRdx); + VmgSetOffsetValid (Ghcb, GhcbRdx); return VmgExit (Ghcb, SVM_EXIT_MONITOR, 0, 0); } @@ -988,9 +932,9 @@ RdtscpExit ( return Status; } - if (!GhcbIsRegValid (Ghcb, GhcbRax) || - !GhcbIsRegValid (Ghcb, GhcbRcx) || - !GhcbIsRegValid (Ghcb, GhcbRdx)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax) || + !VmgIsOffsetValid (Ghcb, GhcbRcx) || + !VmgIsOffsetValid (Ghcb, GhcbRdx)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } Regs->Rax = Ghcb->SaveArea.Rax; @@ -1027,16 +971,16 @@ VmmCallExit ( DecodeModRm (Regs, InstructionData); Ghcb->SaveArea.Rax = Regs->Rax; - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Ghcb->SaveArea.Cpl = (UINT8) (Regs->Cs & 0x3); - GhcbSetRegValid (Ghcb, GhcbCpl); + VmgSetOffsetValid (Ghcb, GhcbCpl); Status = VmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0); if (Status != 0) { return Status; } - if (!GhcbIsRegValid (Ghcb, GhcbRax)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } Regs->Rax = Ghcb->SaveArea.Rax; @@ -1074,15 +1018,15 @@ MsrExit ( case 0x30: // WRMSR ExitInfo1 = 1; Ghcb->SaveArea.Rax = Regs->Rax; - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Ghcb->SaveArea.Rdx = Regs->Rdx; - GhcbSetRegValid (Ghcb, GhcbRdx); + VmgSetOffsetValid (Ghcb, GhcbRdx); // // fall through // case 0x32: // RDMSR Ghcb->SaveArea.Rcx = Regs->Rcx; - GhcbSetRegValid (Ghcb, GhcbRcx); + VmgSetOffsetValid (Ghcb, GhcbRcx); break; default: return UnsupportedExit (Ghcb, Regs, InstructionData); @@ -1094,8 +1038,8 @@ MsrExit ( } if (ExitInfo1 == 0) { - if (!GhcbIsRegValid (Ghcb, GhcbRax) || - !GhcbIsRegValid (Ghcb, GhcbRdx)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax) || + !VmgIsOffsetValid (Ghcb, GhcbRdx)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } Regs->Rax = Ghcb->SaveArea.Rax; @@ -1311,7 +1255,7 @@ IoioExit ( } else { CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1)); } - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0); if (Status != 0) { @@ -1319,7 +1263,7 @@ IoioExit ( } if ((ExitInfo1 & IOIO_TYPE_IN) != 0) { - if (!GhcbIsRegValid (Ghcb, GhcbRax)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1)); @@ -1379,15 +1323,15 @@ CpuidExit ( UINT64 Status; Ghcb->SaveArea.Rax = Regs->Rax; - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Ghcb->SaveArea.Rcx = Regs->Rcx; - GhcbSetRegValid (Ghcb, GhcbRcx); + VmgSetOffsetValid (Ghcb, GhcbRcx); if (Regs->Rax == CPUID_EXTENDED_STATE) { IA32_CR4 Cr4; Cr4.UintN = AsmReadCr4 (); Ghcb->SaveArea.XCr0 = (Cr4.Bits.OSXSAVE == 1) ? AsmXGetBv (0) : 1; - GhcbSetRegValid (Ghcb, GhcbXCr0); + VmgSetOffsetValid (Ghcb, GhcbXCr0); } Status = VmgExit (Ghcb, SVM_EXIT_CPUID, 0, 0); @@ -1395,10 +1339,10 @@ CpuidExit ( return Status; } - if (!GhcbIsRegValid (Ghcb, GhcbRax) || - !GhcbIsRegValid (Ghcb, GhcbRbx) || - !GhcbIsRegValid (Ghcb, GhcbRcx) || - !GhcbIsRegValid (Ghcb, GhcbRdx)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax) || + !VmgIsOffsetValid (Ghcb, GhcbRbx) || + !VmgIsOffsetValid (Ghcb, GhcbRcx) || + !VmgIsOffsetValid (Ghcb, GhcbRdx)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } Regs->Rax = Ghcb->SaveArea.Rax; @@ -1434,15 +1378,15 @@ RdpmcExit ( UINT64 Status; Ghcb->SaveArea.Rcx = Regs->Rcx; - GhcbSetRegValid (Ghcb, GhcbRcx); + VmgSetOffsetValid (Ghcb, GhcbRcx); Status = VmgExit (Ghcb, SVM_EXIT_RDPMC, 0, 0); if (Status != 0) { return Status; } - if (!GhcbIsRegValid (Ghcb, GhcbRax) || - !GhcbIsRegValid (Ghcb, GhcbRdx)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax) || + !VmgIsOffsetValid (Ghcb, GhcbRdx)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } Regs->Rax = Ghcb->SaveArea.Rax; @@ -1480,8 +1424,8 @@ RdtscExit ( return Status; } - if (!GhcbIsRegValid (Ghcb, GhcbRax) || - !GhcbIsRegValid (Ghcb, GhcbRdx)) { + if (!VmgIsOffsetValid (Ghcb, GhcbRax) || + !VmgIsOffsetValid (Ghcb, GhcbRdx)) { return UnsupportedExit (Ghcb, Regs, InstructionData); } Regs->Rax = Ghcb->SaveArea.Rax; @@ -1531,7 +1475,7 @@ Dr7WriteExit ( // Using a value of 0 for ExitInfo1 means RAX holds the value // Ghcb->SaveArea.Rax = *Register; - GhcbSetRegValid (Ghcb, GhcbRax); + VmgSetOffsetValid (Ghcb, GhcbRax); Status = VmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0); if (Status != 0) {