16#define PAGES_PER_2MB_ENTRY 512
36 Msr.GhcbTerminate.Function = GHCB_INFO_TERMINATE_REQUEST;
37 Msr.GhcbTerminate.ReasonCodeSet = GHCB_TERMINATE_GHCB;
38 Msr.GhcbTerminate.ReasonCode = GHCB_TERMINATE_GHCB_GENERAL;
59 IN OUT SVSM_CALL_DATA *SvsmCallData
65 BOOLEAN InterruptState;
79 SvsmCallData->CallPending = &Pending;
84 Msr.SnpVmplRequest.Function = GHCB_INFO_SNP_VMPL_REQUEST;
85 Msr.SnpVmplRequest.Vmpl = 0;
94 Ret = AsmVmgExitSvsm (SvsmCallData);
101 if (InterruptState) {
109 if ((Msr.SnpVmplResponse.Function != GHCB_INFO_SNP_VMPL_RESPONSE) ||
110 (Msr.SnpVmplResponse.ErrorCode != 0))
114 }
while (Ret == SVSM_ERR_INCOMPLETE || Ret == SVSM_ERR_BUSY);
134 SVSM_INFORMATION *SvsmInfo;
136 SvsmInfo = (SVSM_INFORMATION *)(
UINTN)
PcdGet32 (PcdOvmfSnpSecretsBase);
138 return (SvsmInfo !=
NULL && SvsmInfo->SvsmSize != 0);
157 SVSM_INFORMATION *SvsmInfo;
159 SvsmInfo = (SVSM_INFORMATION *)(
UINTN)
PcdGet32 (PcdOvmfSnpSecretsBase);
178 SVSM_INFORMATION *SvsmInfo;
180 SvsmInfo = (SVSM_INFORMATION *)(
UINTN)
PcdGet32 (PcdOvmfSnpSecretsBase);
200 SVSM_CALL_DATA SvsmCallData;
202 SVSM_PVALIDATE_REQUEST *Request;
214 ZeroMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer));
216 Function.Id.Protocol = 0;
217 Function.Id.CallId = 1;
219 Request = (SVSM_PVALIDATE_REQUEST *)Caa->SvsmBuffer;
220 EntryLimit = ((sizeof (Caa->SvsmBuffer) - sizeof (*Request)) /
221 sizeof (Request->Entry[0])) - 1;
223 SvsmCallData.Caa = Caa;
224 SvsmCallData.RaxIn = Function.Uint64;
225 SvsmCallData.RcxIn = (UINT64)(
UINTN)Request;
228 Index = Info->Header.CurrentEntry;
229 EndIndex = Info->Header.EndEntry;
231 while (Index <= EndIndex) {
232 Validate = Info->Entry[Index].Operation == SNP_PAGE_STATE_PRIVATE;
234 Request->Header.Entries++;
235 Request->Entry[Entry].Bits.PageSize = Info->Entry[Index].PageSize;
236 Request->Entry[Entry].Bits.Action = (Validate ==
TRUE) ? 1 : 0;
237 Request->Entry[Entry].Bits.IgnoreCf = 0;
238 Request->Entry[Entry].Bits.Address = Info->Entry[Index].GuestFrameNumber;
241 if ((Entry > EntryLimit) || (Index == EndIndex)) {
243 if ((Ret == SVSM_ERR_PVALIDATE_FAIL_SIZE_MISMATCH) &&
244 (Request->Entry[Request->Header.Next].Bits.PageSize != 0))
249 Index = Index - (Entry - Request->Header.Next) + 2;
252 Gfn = Request->Entry[Request->Header.Next].Bits.Address;
255 ZeroMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer));
258 GfnEnd = Gfn + PAGES_PER_2MB_ENTRY - 1;
259 for ( ; Gfn <= GfnEnd; Gfn++) {
260 Request->Header.Entries++;
261 Request->Entry[Entry].Bits.PageSize = 0;
262 Request->Entry[Entry].Bits.Action = (Validate ==
TRUE) ? 1 : 0;
263 Request->Entry[Entry].Bits.IgnoreCf = 0;
264 Request->Entry[Entry].Bits.Address = Gfn;
267 if ((Entry > EntryLimit) || (Gfn == GfnEnd)) {
273 ZeroMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer));
285 ZeroMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer));
315 StartIndex = Info->Header.CurrentEntry;
316 EndIndex = Info->Header.EndEntry;
318 for ( ; StartIndex <= EndIndex; StartIndex++) {
323 RmpPageSize = Info->Entry[StartIndex].PageSize;
324 Validate = Info->Entry[StartIndex].Operation == SNP_PAGE_STATE_PRIVATE;
326 Ret = AsmPvalidate (RmpPageSize, Validate, Address);
333 if ((Ret == PVALIDATE_RET_SIZE_MISMATCH) && (RmpPageSize == PvalidatePageSize2MB)) {
334 for (Index = 0; Index < PAGES_PER_2MB_ENTRY; Index++) {
335 Ret = AsmPvalidate (PvalidatePageSize4K, Validate, Address);
340 Address = Address + EFI_PAGE_SIZE;
350 "%a:%a: Failed to %a address 0x%Lx Error code %d\n",
353 Validate ?
"Validate" :
"Invalidate",
404 SVSM_CALL_DATA SvsmCallData;
410 Function.Id.Protocol = 0;
413 Function.Id.CallId = 2;
415 SvsmCallData.RaxIn = Function.Uint64;
416 SvsmCallData.RcxIn = (UINT64)(
UINTN)Vmsa;
417 SvsmCallData.RdxIn = (UINT64)(
UINTN)Vmsa + SIZE_4KB;
418 SvsmCallData.R8In = ApicId;
420 Function.Id.CallId = 3;
422 SvsmCallData.RaxIn = Function.Uint64;
423 SvsmCallData.RcxIn = (UINT64)(
UINTN)Vmsa;
428 return (Ret == 0) ?
EFI_SUCCESS : EFI_INVALID_PARAMETER;
466 Rdx |= RMPADJUST_VMSA_PAGE_BIT;
469 Ret = AsmRmpAdjust ((UINT64)(
UINTN)Vmsa, 0, Rdx);
471 return (Ret == 0) ?
EFI_SUCCESS : EFI_INVALID_PARAMETER;
BOOLEAN EFIAPI AmdSvsmIsSvsmPresent(VOID)
UINT8 EFIAPI AmdSvsmSnpGetVmpl(VOID)
STATIC VOID BasePvalidate(IN SNP_PAGE_STATE_CHANGE_INFO *Info)
EFI_STATUS EFIAPI AmdSvsmSnpVmsaRmpAdjust(IN SEV_ES_SAVE_AREA *Vmsa, IN UINT32 ApicId, IN BOOLEAN SetVmsa)
UINT64 EFIAPI AmdSvsmSnpGetCaa(VOID)
VOID EFIAPI AmdSvsmSnpPvalidate(IN SNP_PAGE_STATE_CHANGE_INFO *Info)
STATIC UINTN SvsmMsrProtocol(IN OUT SVSM_CALL_DATA *SvsmCallData)
STATIC VOID SvsmPvalidate(IN SNP_PAGE_STATE_CHANGE_INFO *Info)
STATIC VOID SnpTerminate(VOID)
STATIC EFI_STATUS BaseVmsaRmpAdjust(IN SEV_ES_SAVE_AREA *Vmsa, IN BOOLEAN SetVmsa)
STATIC EFI_STATUS SvsmVmsaRmpAdjust(IN SEV_ES_SAVE_AREA *Vmsa, IN UINT32 ApicId, IN BOOLEAN SetVmsa)
BOOLEAN EFIAPI GetInterruptState(VOID)
VOID EFIAPI CpuDeadLoop(VOID)
VOID EFIAPI MemoryFence(VOID)
VOID EFIAPI EnableInterrupts(VOID)
VOID EFIAPI DisableInterrupts(VOID)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
#define DEBUG(Expression)
#define PcdGet32(TokenName)
UINT64 EFI_PHYSICAL_ADDRESS