#include <PiPei.h>\r
#include <Register/Amd/Msr.h>\r
#include <Register/Intel/SmramSaveStateMap.h>\r
+#include <Library/VmgExitLib.h>\r
\r
#include "Platform.h"\r
\r
+/**\r
+ Handle an SEV-SNP/GHCB protocol check failure.\r
+\r
+ Notify the hypervisor using the VMGEXIT instruction that the SEV-SNP guest\r
+ wishes to be terminated.\r
+\r
+ @param[in] ReasonCode Reason code to provide to the hypervisor for the\r
+ termination request.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+SevEsProtocolFailure (\r
+ IN UINT8 ReasonCode\r
+ )\r
+{\r
+ MSR_SEV_ES_GHCB_REGISTER Msr;\r
+\r
+ //\r
+ // Use the GHCB MSR Protocol to request termination by the hypervisor\r
+ //\r
+ Msr.GhcbPhysicalAddress = 0;\r
+ Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;\r
+ Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;\r
+ Msr.GhcbTerminate.ReasonCode = ReasonCode;\r
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
+\r
+ AsmVmgExit ();\r
+\r
+ ASSERT (FALSE);\r
+ CpuDeadLoop ();\r
+}\r
+\r
+/**\r
+\r
+ This function can be used to register the GHCB GPA.\r
+\r
+ @param[in] Address The physical address to be registered.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+GhcbRegister (\r
+ IN EFI_PHYSICAL_ADDRESS Address\r
+ )\r
+{\r
+ MSR_SEV_ES_GHCB_REGISTER Msr;\r
+ MSR_SEV_ES_GHCB_REGISTER CurrentMsr;\r
+\r
+ //\r
+ // Save the current MSR Value\r
+ //\r
+ CurrentMsr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
+\r
+ //\r
+ // Use the GHCB MSR Protocol to request to register the GPA.\r
+ //\r
+ Msr.GhcbPhysicalAddress = Address & ~EFI_PAGE_MASK;\r
+ Msr.GhcbGpaRegister.Function = GHCB_INFO_GHCB_GPA_REGISTER_REQUEST;\r
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, Msr.GhcbPhysicalAddress);\r
+\r
+ AsmVmgExit ();\r
+\r
+ Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
+\r
+ //\r
+ // If hypervisor responded with a different GPA than requested then fail.\r
+ //\r
+ if ((Msr.GhcbGpaRegister.Function != GHCB_INFO_GHCB_GPA_REGISTER_RESPONSE) ||\r
+ ((Msr.GhcbPhysicalAddress & ~EFI_PAGE_MASK) != Address))\r
+ {\r
+ SevEsProtocolFailure (GHCB_TERMINATE_GHCB_GENERAL);\r
+ }\r
+\r
+ //\r
+ // Restore the MSR\r
+ //\r
+ AsmWriteMsr64 (MSR_SEV_ES_GHCB, CurrentMsr.GhcbPhysicalAddress);\r
+}\r
+\r
/**\r
\r
Initialize SEV-ES support if running as an SEV-ES guest.\r
GhcbBackupBase\r
));\r
\r
+ //\r
+ // SEV-SNP guest requires that GHCB GPA must be registered before using it.\r
+ //\r
+ if (MemEncryptSevSnpIsEnabled ()) {\r
+ GhcbRegister (GhcbBasePa);\r
+ }\r
+\r
AsmWriteMsr64 (MSR_SEV_ES_GHCB, GhcbBasePa);\r
\r
//\r