#include <Library/BaseMemoryLib.h>\r
#include <Library/VmgExitLib.h>\r
#include <Register/Amd/Msr.h>\r
+#include <Register/Intel/Cpuid.h>\r
#include <IndustryStandard/InstructionParsing.h>\r
\r
//\r
return 0;\r
}\r
\r
+/**\r
+ Handle a CPUID event.\r
+\r
+ Use the VMGEXIT instruction to handle a CPUID event.\r
+\r
+ @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication\r
+ Block\r
+ @param[in, out] Regs x64 processor context\r
+ @param[in] InstructionData Instruction parsing context\r
+\r
+ @retval 0 Event handled successfully\r
+ @return New exception value to propagate\r
+\r
+**/\r
+STATIC\r
+UINT64\r
+CpuidExit (\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ )\r
+{\r
+ UINT64 Status;\r
+\r
+ Ghcb->SaveArea.Rax = Regs->Rax;\r
+ GhcbSetRegValid (Ghcb, GhcbRax);\r
+ Ghcb->SaveArea.Rcx = Regs->Rcx;\r
+ GhcbSetRegValid (Ghcb, GhcbRcx);\r
+ if (Regs->Rax == CPUID_EXTENDED_STATE) {\r
+ IA32_CR4 Cr4;\r
+\r
+ Cr4.UintN = AsmReadCr4 ();\r
+ Ghcb->SaveArea.XCr0 = (Cr4.Bits.OSXSAVE == 1) ? AsmXGetBv (0) : 1;\r
+ GhcbSetRegValid (Ghcb, GhcbXCr0);\r
+ }\r
+\r
+ Status = VmgExit (Ghcb, SVM_EXIT_CPUID, 0, 0);\r
+ if (Status != 0) {\r
+ return Status;\r
+ }\r
+\r
+ if (!GhcbIsRegValid (Ghcb, GhcbRax) ||\r
+ !GhcbIsRegValid (Ghcb, GhcbRbx) ||\r
+ !GhcbIsRegValid (Ghcb, GhcbRcx) ||\r
+ !GhcbIsRegValid (Ghcb, GhcbRdx)) {\r
+ return UnsupportedExit (Ghcb, Regs, InstructionData);\r
+ }\r
+ Regs->Rax = Ghcb->SaveArea.Rax;\r
+ Regs->Rbx = Ghcb->SaveArea.Rbx;\r
+ Regs->Rcx = Ghcb->SaveArea.Rcx;\r
+ Regs->Rdx = Ghcb->SaveArea.Rdx;\r
+\r
+ return 0;\r
+}\r
+\r
/**\r
Handle a #VC exception.\r
\r
\r
ExitCode = Regs->ExceptionData;\r
switch (ExitCode) {\r
+ case SVM_EXIT_CPUID:\r
+ NaeExit = CpuidExit;\r
+ break;\r
+\r
case SVM_EXIT_IOIO_PROT:\r
NaeExit = IoioExit;\r
break;\r