73 Regs->Rax = CpuIdData.Regs[0];
74 Regs->Rbx = CpuIdData.Regs[1];
75 Regs->Rcx = CpuIdData.Regs[2];
76 Regs->Rdx = CpuIdData.Regs[3];
109 Write = Veinfo->ExitQualification.Io.Direction ?
FALSE :
TRUE;
110 Size = Veinfo->ExitQualification.Io.Size + 1;
111 Port = Veinfo->ExitQualification.Io.Port;
113 if (Veinfo->ExitQualification.Io.String) {
117 RepCnt = Veinfo->ExitQualification.Io.Rep ? Regs->Rcx : 1;
122 CopyMem (&Val, (VOID *)Regs->Rsi, Size);
126 Status =
TdVmCall (EXIT_REASON_IO_INSTRUCTION, Size, Write, Port, Val, (Write ?
NULL : &Val));
131 if (Write ==
FALSE) {
132 CopyMem ((VOID *)Regs->Rdi, &Val, Size);
136 if (Veinfo->ExitQualification.Io.Rep) {
144 CopyMem (&Val, (VOID *)&Regs->Rax, Size);
147 Status =
TdVmCall (EXIT_REASON_IO_INSTRUCTION, Size, Write, Port, Val, (Write ?
NULL : &Val));
148 if ((Status == 0) && (Write ==
FALSE)) {
149 CopyMem ((VOID *)&Regs->Rax, &Val, Size);
177 Status =
TdVmCall (EXIT_REASON_MSR_READ, Regs->Rcx, 0, 0, 0, &Data);
179 Regs->Rax = Data.Regs.Eax;
180 Regs->Rdx = Data.Regs.Edx;
207 Data.Regs.Eax = (UINT32)Regs->Rax;
208 Data.Regs.Edx = (UINT32)Regs->Rdx;
210 Status =
TdVmCall (EXIT_REASON_MSR_WRITE, Regs->Rcx, Data.Val, 0, 0,
NULL);
218TdxDecodeInstruction (
224 DEBUG ((DEBUG_INFO,
"TDX: #TD[EPT] instruction (%p):", Rip));
225 for (i = 0; i < 15; i++) {
226 DEBUG ((DEBUG_INFO,
"%02x:", Rip[i]));
229 DEBUG ((DEBUG_INFO,
"\n"));
232#define TDX_DECODER_BUG_ON(x) \
234 TdxDecodeInstruction(Rip); \
235 TdVmCall(TDVMCALL_HALT, 0, 0, 0, 0, 0); \
247 case 0:
return &Regs->Rax;
249 case 1:
return &Regs->Rcx;
251 case 2:
return &Regs->Rdx;
253 case 3:
return &Regs->Rbx;
255 case 4:
return &Regs->Rsp;
257 case 5:
return &Regs->Rbp;
259 case 6:
return &Regs->Rsi;
261 case 7:
return &Regs->Rdi;
263 case 8:
return &Regs->R8;
265 case 9:
return &Regs->R9;
267 case 10:
return &Regs->R10;
269 case 11:
return &Regs->R11;
271 case 12:
return &Regs->R12;
273 case 13:
return &Regs->R13;
275 case 14:
return &Regs->R14;
277 case 15:
return &Regs->R15;
315 Rip = (UINT8 *)Regs->Rip;
327 if (OpCode == 0x66) {
329 }
else if ((OpCode == 0x64) || (OpCode == 0x65) || (OpCode == 0x67)) {
331 }
else if ((OpCode >= 0x40) && (OpCode <= 0x4f)) {
342 TDX_DECODER_BUG_ON (((UINT64)Rip - Regs->Rip) > 13);
348 if (OpCode == 0x0F) {
362 MmioSize = Rex.Bits.W ? 8 : OpSize;
368 TDX_DECODER_BUG_ON (MmioSize == 1 && ModRm.Bits.Reg > 4 && !SeenRex && OpCode != 0xB6);
369 Reg = GetRegFromContext (Regs, ModRm.Bits.Reg | ((
int)Rex.Bits.R << 3));
370 TDX_DECODER_BUG_ON (!Reg);
372 if (ModRm.Bits.Rm == 4) {
376 if ((ModRm.Bits.Mod == 2) || ((ModRm.Bits.Mod == 0) && (ModRm.Bits.Rm == 5))) {
378 }
else if (ModRm.Bits.Mod == 1) {
385 CopyMem ((
void *)&Val, Reg, MmioSize);
386 Status =
TdVmCall (TDVMCALL_MMIO, MmioSize, 1, Veinfo->GuestPA, Val, 0);
389 CopyMem ((
void *)&Val, Rip, OpSize);
390 Status =
TdVmCall (TDVMCALL_MMIO, MmioSize, 1, Veinfo->GuestPA, Val, 0);
401 RegSize = Rex.Bits.W ? 8 : OpSize;
407 RegSize = MmioSize == 4 ? 8 : MmioSize;
411 Status =
TdVmCall (TDVMCALL_MMIO, MmioSize, 0, Veinfo->GuestPA, 0, &Val);
414 CopyMem (Reg, (
void *)&Val, MmioSize);
419 TDX_DECODER_BUG_ON (((UINT64)Rip - Regs->Rip) > 15);
425 Veinfo->ExitInstructionLength = (UINT32)((UINT64)Rip - Regs->Rip);
458 Regs = SystemContext.SystemContextX64;
459 Status =
TdCall (TDCALL_TDGETVEINFO, 0, 0, 0, &ReturnData);
462 DEBUG ((DEBUG_ERROR,
"#VE happened. TDGETVEINFO failed with Status = 0x%llx\n", Status));
463 TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
466 switch (ReturnData.VeInfo.ExitReason) {
467 case EXIT_REASON_CPUID:
468 Status =
CpuIdExit (Regs, &ReturnData.VeInfo);
471 "CPUID #VE happened, ExitReasion is %d, ExitQualification = 0x%x.\n",
472 ReturnData.VeInfo.ExitReason,
473 ReturnData.VeInfo.ExitQualification.Val
477 case EXIT_REASON_HLT:
478 Status =
TdVmCall (EXIT_REASON_HLT, 0, 0, 0, 0, 0);
481 case EXIT_REASON_IO_INSTRUCTION:
482 Status =
IoExit (Regs, &ReturnData.VeInfo);
485 "IO_Instruction #VE happened, ExitReasion is %d, ExitQualification = 0x%x.\n",
486 ReturnData.VeInfo.ExitReason,
487 ReturnData.VeInfo.ExitQualification.Val
491 case EXIT_REASON_MSR_READ:
495 "RDMSR #VE happened, ExitReasion is %d, ExitQualification = 0x%x. Regs->Rcx=0x%llx, Status = 0x%llx\n",
496 ReturnData.VeInfo.ExitReason,
497 ReturnData.VeInfo.ExitQualification.Val,
503 case EXIT_REASON_MSR_WRITE:
507 "WRMSR #VE happened, ExitReasion is %d, ExitQualification = 0x%x. Regs->Rcx=0x%llx, Status = 0x%llx\n",
508 ReturnData.VeInfo.ExitReason,
509 ReturnData.VeInfo.ExitQualification.Val,
515 case EXIT_REASON_EPT_VIOLATION:
516 Status =
MmioExit (Regs, &ReturnData.VeInfo);
519 "MMIO #VE happened, ExitReasion is %d, ExitQualification = 0x%x.\n",
520 ReturnData.VeInfo.ExitReason,
521 ReturnData.VeInfo.ExitQualification.Val
525 case EXIT_REASON_VMCALL:
526 case EXIT_REASON_MWAIT_INSTRUCTION:
527 case EXIT_REASON_MONITOR_INSTRUCTION:
528 case EXIT_REASON_WBINVD:
529 case EXIT_REASON_RDPMC:
536 "Unsupported #VE happened, ExitReason is %d, ExitQualification = 0x%x.\n",
537 ReturnData.VeInfo.ExitReason,
538 ReturnData.VeInfo.ExitQualification.Val
548 "#VE Error (0x%llx) returned from host, ExitReason is %d, ExitQualification = 0x%x.\n",
550 ReturnData.VeInfo.ExitReason,
551 ReturnData.VeInfo.ExitQualification.Val
554 TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
557 SystemContext.SystemContextX64->Rip += ReturnData.VeInfo.ExitInstructionLength;
VOID EFIAPI CpuDeadLoop(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define DEBUG(Expression)
#define ASSERT(Expression)
UINTN EFIAPI TdCall(IN UINT64 Leaf, IN UINT64 Arg1, IN UINT64 Arg2, IN UINT64 Arg3, IN OUT VOID *Results)
UINTN EFIAPI TdVmCall(IN UINT64 Leaf, IN UINT64 Arg1, IN UINT64 Arg2, IN UINT64 Arg3, IN UINT64 Arg4, IN OUT VOID *Results)
EFI_STATUS EFIAPI TdVmCallCpuid(IN UINT64 Eax, IN UINT64 Ecx, OUT VOID *Results)
STATIC INTN EFIAPI MmioExit(IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, IN TDCALL_VEINFO_RETURN_DATA *Veinfo)
STATIC UINT64 EFIAPI CpuIdExit(IN EFI_SYSTEM_CONTEXT_X64 *Regs, IN TDCALL_VEINFO_RETURN_DATA *Veinfo)
EFI_STATUS EFIAPI VmTdExitHandleVe(IN OUT EFI_EXCEPTION_TYPE *ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext)
STATIC UINT64 ReadMsrExit(IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, IN TDCALL_VEINFO_RETURN_DATA *Veinfo)
STATIC UINT64 EFIAPI IoExit(IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, IN TDCALL_VEINFO_RETURN_DATA *Veinfo)
STATIC UINT64 WriteMsrExit(IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, IN TDCALL_VEINFO_RETURN_DATA *Veinfo)