#include <IndustryStandard/InstructionParsing.h>\r
\r
#include "CcExitVcHandler.h"\r
-\r
-//\r
-// Instruction execution mode definition\r
-//\r
-typedef enum {\r
- LongMode64Bit = 0,\r
- LongModeCompat32Bit,\r
- LongModeCompat16Bit,\r
-} SEV_ES_INSTRUCTION_MODE;\r
-\r
-//\r
-// Instruction size definition (for operand and address)\r
-//\r
-typedef enum {\r
- Size8Bits = 0,\r
- Size16Bits,\r
- Size32Bits,\r
- Size64Bits,\r
-} SEV_ES_INSTRUCTION_SIZE;\r
-\r
-//\r
-// Intruction segment definition\r
-//\r
-typedef enum {\r
- SegmentEs = 0,\r
- SegmentCs,\r
- SegmentSs,\r
- SegmentDs,\r
- SegmentFs,\r
- SegmentGs,\r
-} SEV_ES_INSTRUCTION_SEGMENT;\r
-\r
-//\r
-// Instruction rep function definition\r
-//\r
-typedef enum {\r
- RepNone = 0,\r
- RepZ,\r
- RepNZ,\r
-} SEV_ES_INSTRUCTION_REP;\r
-\r
-typedef struct {\r
- UINT8 Rm;\r
- UINT8 Reg;\r
- UINT8 Mod;\r
-} SEV_ES_INSTRUCTION_MODRM_EXT;\r
-\r
-typedef struct {\r
- UINT8 Base;\r
- UINT8 Index;\r
- UINT8 Scale;\r
-} SEV_ES_INSTRUCTION_SIB_EXT;\r
-\r
-//\r
-// Instruction opcode definition\r
-//\r
-typedef struct {\r
- SEV_ES_INSTRUCTION_MODRM_EXT ModRm;\r
-\r
- SEV_ES_INSTRUCTION_SIB_EXT Sib;\r
-\r
- UINTN RegData;\r
- UINTN RmData;\r
-} SEV_ES_INSTRUCTION_OPCODE_EXT;\r
-\r
-//\r
-// Instruction parsing context definition\r
-//\r
-typedef struct {\r
- GHCB *Ghcb;\r
-\r
- SEV_ES_INSTRUCTION_MODE Mode;\r
- SEV_ES_INSTRUCTION_SIZE DataSize;\r
- SEV_ES_INSTRUCTION_SIZE AddrSize;\r
- BOOLEAN SegmentSpecified;\r
- SEV_ES_INSTRUCTION_SEGMENT Segment;\r
- SEV_ES_INSTRUCTION_REP RepMode;\r
-\r
- UINT8 *Begin;\r
- UINT8 *End;\r
-\r
- UINT8 *Prefixes;\r
- UINT8 *OpCodes;\r
- UINT8 *Displacement;\r
- UINT8 *Immediate;\r
-\r
- INSTRUCTION_REX_PREFIX RexPrefix;\r
-\r
- BOOLEAN ModRmPresent;\r
- INSTRUCTION_MODRM ModRm;\r
-\r
- BOOLEAN SibPresent;\r
- INSTRUCTION_SIB Sib;\r
-\r
- UINTN PrefixSize;\r
- UINTN OpCodeSize;\r
- UINTN DisplacementSize;\r
- UINTN ImmediateSize;\r
-\r
- SEV_ES_INSTRUCTION_OPCODE_EXT Ext;\r
-} SEV_ES_INSTRUCTION_DATA;\r
+#include "CcInstruction.h"\r
\r
//\r
// Non-automatic Exit function prototype\r
typedef\r
UINT64\r
(*NAE_EXIT) (\r
- GHCB *Ghcb,\r
- EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ GHCB *Ghcb,\r
+ EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ CC_INSTRUCTION_DATA *InstructionData\r
);\r
\r
//\r
SEV_SNP_CPUID_FUNCTION function[0];\r
} SEV_SNP_CPUID_INFO;\r
\r
-/**\r
- Return a pointer to the contents of the specified register.\r
-\r
- Based upon the input register, return a pointer to the registers contents\r
- in the x86 processor context.\r
-\r
- @param[in] Regs x64 processor context\r
- @param[in] Register Register to obtain pointer for\r
-\r
- @return Pointer to the contents of the requested register\r
-\r
-**/\r
-STATIC\r
-UINT64 *\r
-GetRegisterPointer (\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN UINT8 Register\r
- )\r
-{\r
- UINT64 *Reg;\r
-\r
- switch (Register) {\r
- case 0:\r
- Reg = &Regs->Rax;\r
- break;\r
- case 1:\r
- Reg = &Regs->Rcx;\r
- break;\r
- case 2:\r
- Reg = &Regs->Rdx;\r
- break;\r
- case 3:\r
- Reg = &Regs->Rbx;\r
- break;\r
- case 4:\r
- Reg = &Regs->Rsp;\r
- break;\r
- case 5:\r
- Reg = &Regs->Rbp;\r
- break;\r
- case 6:\r
- Reg = &Regs->Rsi;\r
- break;\r
- case 7:\r
- Reg = &Regs->Rdi;\r
- break;\r
- case 8:\r
- Reg = &Regs->R8;\r
- break;\r
- case 9:\r
- Reg = &Regs->R9;\r
- break;\r
- case 10:\r
- Reg = &Regs->R10;\r
- break;\r
- case 11:\r
- Reg = &Regs->R11;\r
- break;\r
- case 12:\r
- Reg = &Regs->R12;\r
- break;\r
- case 13:\r
- Reg = &Regs->R13;\r
- break;\r
- case 14:\r
- Reg = &Regs->R14;\r
- break;\r
- case 15:\r
- Reg = &Regs->R15;\r
- break;\r
- default:\r
- Reg = NULL;\r
- }\r
-\r
- ASSERT (Reg != NULL);\r
-\r
- return Reg;\r
-}\r
-\r
-/**\r
- Update the instruction parsing context for displacement bytes.\r
-\r
- @param[in, out] InstructionData Instruction parsing context\r
- @param[in] Size The instruction displacement size\r
-\r
-**/\r
-STATIC\r
-VOID\r
-UpdateForDisplacement (\r
- IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData,\r
- IN UINTN Size\r
- )\r
-{\r
- InstructionData->DisplacementSize = Size;\r
- InstructionData->Immediate += Size;\r
- InstructionData->End += Size;\r
-}\r
-\r
-/**\r
- Determine if an instruction address if RIP relative.\r
-\r
- Examine the instruction parsing context to determine if the address offset\r
- is relative to the instruction pointer.\r
-\r
- @param[in] InstructionData Instruction parsing context\r
-\r
- @retval TRUE Instruction addressing is RIP relative\r
- @retval FALSE Instruction addressing is not RIP relative\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-IsRipRelative (\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
- )\r
-{\r
- SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;\r
-\r
- Ext = &InstructionData->Ext;\r
-\r
- return ((InstructionData->Mode == LongMode64Bit) &&\r
- (Ext->ModRm.Mod == 0) &&\r
- (Ext->ModRm.Rm == 5) &&\r
- (InstructionData->SibPresent == FALSE));\r
-}\r
-\r
-/**\r
- Return the effective address of a memory operand.\r
-\r
- Examine the instruction parsing context to obtain the effective memory\r
- address of a memory operand.\r
-\r
- @param[in] Regs x64 processor context\r
- @param[in] InstructionData Instruction parsing context\r
-\r
- @return The memory operand effective address\r
-\r
-**/\r
-STATIC\r
-UINT64\r
-GetEffectiveMemoryAddress (\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
- )\r
-{\r
- SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;\r
- UINT64 EffectiveAddress;\r
-\r
- Ext = &InstructionData->Ext;\r
- EffectiveAddress = 0;\r
-\r
- if (IsRipRelative (InstructionData)) {\r
- //\r
- // RIP-relative displacement is a 32-bit signed value\r
- //\r
- INT32 RipRelative;\r
-\r
- RipRelative = *(INT32 *)InstructionData->Displacement;\r
-\r
- UpdateForDisplacement (InstructionData, 4);\r
-\r
- //\r
- // Negative displacement is handled by standard UINT64 wrap-around.\r
- //\r
- return Regs->Rip + (UINT64)RipRelative;\r
- }\r
-\r
- switch (Ext->ModRm.Mod) {\r
- case 1:\r
- UpdateForDisplacement (InstructionData, 1);\r
- EffectiveAddress += (UINT64)(*(INT8 *)(InstructionData->Displacement));\r
- break;\r
- case 2:\r
- switch (InstructionData->AddrSize) {\r
- case Size16Bits:\r
- UpdateForDisplacement (InstructionData, 2);\r
- EffectiveAddress += (UINT64)(*(INT16 *)(InstructionData->Displacement));\r
- break;\r
- default:\r
- UpdateForDisplacement (InstructionData, 4);\r
- EffectiveAddress += (UINT64)(*(INT32 *)(InstructionData->Displacement));\r
- break;\r
- }\r
-\r
- break;\r
- }\r
-\r
- if (InstructionData->SibPresent) {\r
- INT64 Displacement;\r
-\r
- if (Ext->Sib.Index != 4) {\r
- CopyMem (\r
- &Displacement,\r
- GetRegisterPointer (Regs, Ext->Sib.Index),\r
- sizeof (Displacement)\r
- );\r
- Displacement *= (INT64)(1 << Ext->Sib.Scale);\r
-\r
- //\r
- // Negative displacement is handled by standard UINT64 wrap-around.\r
- //\r
- EffectiveAddress += (UINT64)Displacement;\r
- }\r
-\r
- if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) {\r
- EffectiveAddress += *GetRegisterPointer (Regs, Ext->Sib.Base);\r
- } else {\r
- UpdateForDisplacement (InstructionData, 4);\r
- EffectiveAddress += (UINT64)(*(INT32 *)(InstructionData->Displacement));\r
- }\r
- } else {\r
- EffectiveAddress += *GetRegisterPointer (Regs, Ext->ModRm.Rm);\r
- }\r
-\r
- return EffectiveAddress;\r
-}\r
-\r
-/**\r
- Decode a ModRM byte.\r
-\r
- Examine the instruction parsing context to decode a ModRM byte and the SIB\r
- byte, if present.\r
-\r
- @param[in] Regs x64 processor context\r
- @param[in, out] InstructionData Instruction parsing context\r
-\r
-**/\r
-STATIC\r
-VOID\r
-DecodeModRm (\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData\r
- )\r
-{\r
- SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;\r
- INSTRUCTION_REX_PREFIX *RexPrefix;\r
- INSTRUCTION_MODRM *ModRm;\r
- INSTRUCTION_SIB *Sib;\r
-\r
- RexPrefix = &InstructionData->RexPrefix;\r
- Ext = &InstructionData->Ext;\r
- ModRm = &InstructionData->ModRm;\r
- Sib = &InstructionData->Sib;\r
-\r
- InstructionData->ModRmPresent = TRUE;\r
- ModRm->Uint8 = *(InstructionData->End);\r
-\r
- InstructionData->Displacement++;\r
- InstructionData->Immediate++;\r
- InstructionData->End++;\r
-\r
- Ext->ModRm.Mod = ModRm->Bits.Mod;\r
- Ext->ModRm.Reg = (RexPrefix->Bits.BitR << 3) | ModRm->Bits.Reg;\r
- Ext->ModRm.Rm = (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm;\r
-\r
- Ext->RegData = *GetRegisterPointer (Regs, Ext->ModRm.Reg);\r
-\r
- if (Ext->ModRm.Mod == 3) {\r
- Ext->RmData = *GetRegisterPointer (Regs, Ext->ModRm.Rm);\r
- } else {\r
- if (ModRm->Bits.Rm == 4) {\r
- InstructionData->SibPresent = TRUE;\r
- Sib->Uint8 = *(InstructionData->End);\r
-\r
- InstructionData->Displacement++;\r
- InstructionData->Immediate++;\r
- InstructionData->End++;\r
-\r
- Ext->Sib.Scale = Sib->Bits.Scale;\r
- Ext->Sib.Index = (RexPrefix->Bits.BitX << 3) | Sib->Bits.Index;\r
- Ext->Sib.Base = (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base;\r
- }\r
-\r
- Ext->RmData = GetEffectiveMemoryAddress (Regs, InstructionData);\r
- }\r
-}\r
-\r
-/**\r
- Decode instruction prefixes.\r
-\r
- Parse the instruction data to track the instruction prefixes that have\r
- been used.\r
-\r
- @param[in] Regs x64 processor context\r
- @param[in, out] InstructionData Instruction parsing context\r
-\r
-**/\r
-STATIC\r
-VOID\r
-DecodePrefixes (\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData\r
- )\r
-{\r
- SEV_ES_INSTRUCTION_MODE Mode;\r
- SEV_ES_INSTRUCTION_SIZE ModeDataSize;\r
- SEV_ES_INSTRUCTION_SIZE ModeAddrSize;\r
- UINT8 *Byte;\r
-\r
- //\r
- // Always in 64-bit mode\r
- //\r
- Mode = LongMode64Bit;\r
- ModeDataSize = Size32Bits;\r
- ModeAddrSize = Size64Bits;\r
-\r
- InstructionData->Mode = Mode;\r
- InstructionData->DataSize = ModeDataSize;\r
- InstructionData->AddrSize = ModeAddrSize;\r
-\r
- InstructionData->Prefixes = InstructionData->Begin;\r
-\r
- Byte = InstructionData->Prefixes;\r
- for ( ; ; Byte++, InstructionData->PrefixSize++) {\r
- //\r
- // Check the 0x40 to 0x4F range using an if statement here since some\r
- // compilers don't like the "case 0x40 ... 0x4F:" syntax. This avoids\r
- // 16 case statements below.\r
- //\r
- if ((*Byte >= REX_PREFIX_START) && (*Byte <= REX_PREFIX_STOP)) {\r
- InstructionData->RexPrefix.Uint8 = *Byte;\r
- if ((*Byte & REX_64BIT_OPERAND_SIZE_MASK) != 0) {\r
- InstructionData->DataSize = Size64Bits;\r
- }\r
-\r
- continue;\r
- }\r
-\r
- switch (*Byte) {\r
- case OVERRIDE_SEGMENT_CS:\r
- case OVERRIDE_SEGMENT_DS:\r
- case OVERRIDE_SEGMENT_ES:\r
- case OVERRIDE_SEGMENT_SS:\r
- if (Mode != LongMode64Bit) {\r
- InstructionData->SegmentSpecified = TRUE;\r
- InstructionData->Segment = (*Byte >> 3) & 3;\r
- }\r
-\r
- break;\r
-\r
- case OVERRIDE_SEGMENT_FS:\r
- case OVERRIDE_SEGMENT_GS:\r
- InstructionData->SegmentSpecified = TRUE;\r
- InstructionData->Segment = *Byte & 7;\r
- break;\r
-\r
- case OVERRIDE_OPERAND_SIZE:\r
- if (InstructionData->RexPrefix.Uint8 == 0) {\r
- InstructionData->DataSize =\r
- (Mode == LongMode64Bit) ? Size16Bits :\r
- (Mode == LongModeCompat32Bit) ? Size16Bits :\r
- (Mode == LongModeCompat16Bit) ? Size32Bits : 0;\r
- }\r
-\r
- break;\r
-\r
- case OVERRIDE_ADDRESS_SIZE:\r
- InstructionData->AddrSize =\r
- (Mode == LongMode64Bit) ? Size32Bits :\r
- (Mode == LongModeCompat32Bit) ? Size16Bits :\r
- (Mode == LongModeCompat16Bit) ? Size32Bits : 0;\r
- break;\r
-\r
- case LOCK_PREFIX:\r
- break;\r
-\r
- case REPZ_PREFIX:\r
- InstructionData->RepMode = RepZ;\r
- break;\r
-\r
- case REPNZ_PREFIX:\r
- InstructionData->RepMode = RepNZ;\r
- break;\r
-\r
- default:\r
- InstructionData->OpCodes = Byte;\r
- InstructionData->OpCodeSize = (*Byte == TWO_BYTE_OPCODE_ESCAPE) ? 2 : 1;\r
-\r
- InstructionData->End = Byte + InstructionData->OpCodeSize;\r
- InstructionData->Displacement = InstructionData->End;\r
- InstructionData->Immediate = InstructionData->End;\r
- return;\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Determine instruction length\r
-\r
- Return the total length of the parsed instruction.\r
-\r
- @param[in] InstructionData Instruction parsing context\r
-\r
- @return Length of parsed instruction\r
-\r
-**/\r
-STATIC\r
-UINT64\r
-InstructionLength (\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
- )\r
-{\r
- return (UINT64)(InstructionData->End - InstructionData->Begin);\r
-}\r
-\r
-/**\r
- Initialize the instruction parsing context.\r
-\r
- Initialize the instruction parsing context, which includes decoding the\r
- instruction prefixes.\r
-\r
- @param[in, out] InstructionData Instruction parsing context\r
- @param[in] Ghcb Pointer to the Guest-Hypervisor Communication\r
- Block\r
- @param[in] Regs x64 processor context\r
-\r
-**/\r
-STATIC\r
-VOID\r
-InitInstructionData (\r
- IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData,\r
- IN GHCB *Ghcb,\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs\r
- )\r
-{\r
- SetMem (InstructionData, sizeof (*InstructionData), 0);\r
- InstructionData->Ghcb = Ghcb;\r
- InstructionData->Begin = (UINT8 *)Regs->Rip;\r
- InstructionData->End = (UINT8 *)Regs->Rip;\r
-\r
- DecodePrefixes (Regs, InstructionData);\r
-}\r
-\r
/**\r
Report an unsupported event to the hypervisor\r
\r
STATIC\r
UINT64\r
UnsupportedExit (\r
- IN GHCB *Ghcb,\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN GHCB *Ghcb,\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 Status;\r
STATIC\r
UINT64\r
MmioExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN OUT CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 ExitInfo1, ExitInfo2, Status;\r
// fall through\r
//\r
case 0x89:\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
Bytes = ((Bytes != 0) ? Bytes :\r
(InstructionData->DataSize == Size16Bits) ? 2 :\r
(InstructionData->DataSize == Size32Bits) ? 4 :\r
// fall through\r
//\r
case 0xC7:\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
Bytes = ((Bytes != 0) ? Bytes :\r
(InstructionData->DataSize == Size16Bits) ? 2 :\r
(InstructionData->DataSize == Size32Bits) ? 4 :\r
// fall through\r
//\r
case 0x8B:\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
Bytes = ((Bytes != 0) ? Bytes :\r
(InstructionData->DataSize == Size16Bits) ? 2 :\r
(InstructionData->DataSize == Size32Bits) ? 4 :\r
return Status;\r
}\r
\r
- Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);\r
+ Register = CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);\r
if (Bytes == 4) {\r
//\r
// Zero-extend for 32-bit operation\r
// fall through\r
//\r
case 0xB7:\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
Bytes = (Bytes != 0) ? Bytes : 2;\r
\r
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);\r
return Status;\r
}\r
\r
- Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);\r
+ Register = CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);\r
SetMem (Register, (UINTN)(1 << InstructionData->DataSize), 0);\r
CopyMem (Register, Ghcb->SharedBuffer, Bytes);\r
break;\r
// fall through\r
//\r
case 0xBF:\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
Bytes = (Bytes != 0) ? Bytes : 2;\r
\r
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);\r
SignByte = ((*Data & BIT15) != 0) ? 0xFF : 0x00;\r
}\r
\r
- Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);\r
+ Register = CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);\r
SetMem (Register, (UINTN)(1 << InstructionData->DataSize), SignByte);\r
CopyMem (Register, Ghcb->SharedBuffer, Bytes);\r
break;\r
STATIC\r
UINT64\r
MwaitExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
\r
Ghcb->SaveArea.Rax = Regs->Rax;\r
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);\r
STATIC\r
UINT64\r
MonitorExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
\r
Ghcb->SaveArea.Rax = Regs->Rax; // Identity mapped, so VA = PA\r
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);\r
STATIC\r
UINT64\r
WbinvdExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
return CcExitVmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0);\r
STATIC\r
UINT64\r
RdtscpExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 Status;\r
\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
\r
Status = CcExitVmgExit (Ghcb, SVM_EXIT_RDTSCP, 0, 0);\r
if (Status != 0) {\r
STATIC\r
UINT64\r
VmmCallExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 Status;\r
\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
\r
Ghcb->SaveArea.Rax = Regs->Rax;\r
CcExitVmgSetOffsetValid (Ghcb, GhcbRax);\r
STATIC\r
UINT64\r
MsrExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 ExitInfo1, Status;\r
STATIC\r
UINT64\r
IoioExitInfo (\r
- IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN OUT CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 ExitInfo;\r
STATIC\r
UINT64\r
IoioExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 ExitInfo1, ExitInfo2, Status;\r
STATIC\r
UINT64\r
InvdExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
return CcExitVmgExit (Ghcb, SVM_EXIT_INVD, 0, 0);\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
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
BOOLEAN Unsupported;\r
STATIC\r
UINT64\r
RdpmcExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 Status;\r
STATIC\r
UINT64\r
RdtscExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
UINT64 Status;\r
STATIC\r
UINT64\r
Dr7WriteExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
- SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;\r
- SEV_ES_PER_CPU_DATA *SevEsData;\r
- UINT64 *Register;\r
- UINT64 Status;\r
+ CC_INSTRUCTION_OPCODE_EXT *Ext;\r
+ SEV_ES_PER_CPU_DATA *SevEsData;\r
+ UINT64 *Register;\r
+ UINT64 Status;\r
\r
Ext = &InstructionData->Ext;\r
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);\r
\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
\r
//\r
// MOV DRn always treats MOD == 3 no matter how encoded\r
//\r
- Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);\r
+ Register = CcGetRegisterPointer (Regs, Ext->ModRm.Rm);\r
\r
//\r
// Using a value of 0 for ExitInfo1 means RAX holds the value\r
STATIC\r
UINT64\r
Dr7ReadExit (\r
- IN OUT GHCB *Ghcb,\r
- IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
- IN SEV_ES_INSTRUCTION_DATA *InstructionData\r
+ IN OUT GHCB *Ghcb,\r
+ IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
)\r
{\r
- SEV_ES_INSTRUCTION_OPCODE_EXT *Ext;\r
- SEV_ES_PER_CPU_DATA *SevEsData;\r
- UINT64 *Register;\r
+ CC_INSTRUCTION_OPCODE_EXT *Ext;\r
+ SEV_ES_PER_CPU_DATA *SevEsData;\r
+ UINT64 *Register;\r
\r
Ext = &InstructionData->Ext;\r
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);\r
\r
- DecodeModRm (Regs, InstructionData);\r
+ CcDecodeModRm (Regs, InstructionData);\r
\r
//\r
// MOV DRn always treats MOD == 3 no matter how encoded\r
//\r
- Register = GetRegisterPointer (Regs, Ext->ModRm.Rm);\r
+ Register = CcGetRegisterPointer (Regs, Ext->ModRm.Rm);\r
\r
//\r
// If there is a cached valued for DR7, return that. Otherwise return the\r
IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
)\r
{\r
- EFI_SYSTEM_CONTEXT_X64 *Regs;\r
- NAE_EXIT NaeExit;\r
- SEV_ES_INSTRUCTION_DATA InstructionData;\r
- UINT64 ExitCode, Status;\r
- EFI_STATUS VcRet;\r
- BOOLEAN InterruptState;\r
+ EFI_SYSTEM_CONTEXT_X64 *Regs;\r
+ NAE_EXIT NaeExit;\r
+ CC_INSTRUCTION_DATA InstructionData;\r
+ UINT64 ExitCode, Status;\r
+ EFI_STATUS VcRet;\r
+ BOOLEAN InterruptState;\r
\r
VcRet = EFI_SUCCESS;\r
\r
NaeExit = UnsupportedExit;\r
}\r
\r
- InitInstructionData (&InstructionData, Ghcb, Regs);\r
+ CcInitInstructionData (&InstructionData, Ghcb, Regs);\r
\r
Status = NaeExit (Ghcb, Regs, &InstructionData);\r
if (Status == 0) {\r
- Regs->Rip += InstructionLength (&InstructionData);\r
+ Regs->Rip += CcInstructionLength (&InstructionData);\r
} else {\r
GHCB_EVENT_INJECTION Event;\r
\r
--- /dev/null
+/** @file\r
+ X64 Instruction function.\r
+\r
+ Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Uefi.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Register/Intel/Cpuid.h>\r
+#include <IndustryStandard/InstructionParsing.h>\r
+#include "CcInstruction.h"\r
+\r
+#define MAX_INSTRUCTION_LENGTH 15\r
+\r
+/**\r
+ Return a pointer to the contents of the specified register.\r
+\r
+ Based upon the input register, return a pointer to the registers contents\r
+ in the x86 processor context.\r
+\r
+ @param[in] Regs x64 processor context\r
+ @param[in] Register Register to obtain pointer for\r
+\r
+ @return Pointer to the contents of the requested register\r
+\r
+**/\r
+UINT64 *\r
+CcGetRegisterPointer (\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN UINT8 Register\r
+ )\r
+{\r
+ UINT64 *Reg;\r
+\r
+ switch (Register) {\r
+ case 0:\r
+ Reg = &Regs->Rax;\r
+ break;\r
+ case 1:\r
+ Reg = &Regs->Rcx;\r
+ break;\r
+ case 2:\r
+ Reg = &Regs->Rdx;\r
+ break;\r
+ case 3:\r
+ Reg = &Regs->Rbx;\r
+ break;\r
+ case 4:\r
+ Reg = &Regs->Rsp;\r
+ break;\r
+ case 5:\r
+ Reg = &Regs->Rbp;\r
+ break;\r
+ case 6:\r
+ Reg = &Regs->Rsi;\r
+ break;\r
+ case 7:\r
+ Reg = &Regs->Rdi;\r
+ break;\r
+ case 8:\r
+ Reg = &Regs->R8;\r
+ break;\r
+ case 9:\r
+ Reg = &Regs->R9;\r
+ break;\r
+ case 10:\r
+ Reg = &Regs->R10;\r
+ break;\r
+ case 11:\r
+ Reg = &Regs->R11;\r
+ break;\r
+ case 12:\r
+ Reg = &Regs->R12;\r
+ break;\r
+ case 13:\r
+ Reg = &Regs->R13;\r
+ break;\r
+ case 14:\r
+ Reg = &Regs->R14;\r
+ break;\r
+ case 15:\r
+ Reg = &Regs->R15;\r
+ break;\r
+ default:\r
+ Reg = NULL;\r
+ }\r
+\r
+ ASSERT (Reg != NULL);\r
+\r
+ return Reg;\r
+}\r
+\r
+/**\r
+ Update the instruction parsing context for displacement bytes.\r
+\r
+ @param[in, out] InstructionData Instruction parsing context\r
+ @param[in] Size The instruction displacement size\r
+\r
+**/\r
+STATIC\r
+VOID\r
+UpdateForDisplacement (\r
+ IN OUT CC_INSTRUCTION_DATA *InstructionData,\r
+ IN UINTN Size\r
+ )\r
+{\r
+ InstructionData->DisplacementSize = Size;\r
+ InstructionData->Immediate += Size;\r
+ InstructionData->End += Size;\r
+}\r
+\r
+/**\r
+ Determine if an instruction address if RIP relative.\r
+\r
+ Examine the instruction parsing context to determine if the address offset\r
+ is relative to the instruction pointer.\r
+\r
+ @param[in] InstructionData Instruction parsing context\r
+\r
+ @retval TRUE Instruction addressing is RIP relative\r
+ @retval FALSE Instruction addressing is not RIP relative\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+IsRipRelative (\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
+ )\r
+{\r
+ CC_INSTRUCTION_OPCODE_EXT *Ext;\r
+\r
+ Ext = &InstructionData->Ext;\r
+\r
+ return ((InstructionData->Mode == LongMode64Bit) &&\r
+ (Ext->ModRm.Mod == 0) &&\r
+ (Ext->ModRm.Rm == 5) &&\r
+ (InstructionData->SibPresent == FALSE));\r
+}\r
+\r
+/**\r
+ Return the effective address of a memory operand.\r
+\r
+ Examine the instruction parsing context to obtain the effective memory\r
+ address of a memory operand.\r
+\r
+ @param[in] Regs x64 processor context\r
+ @param[in] InstructionData Instruction parsing context\r
+\r
+ @return The memory operand effective address\r
+\r
+**/\r
+STATIC\r
+UINT64\r
+GetEffectiveMemoryAddress (\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
+ )\r
+{\r
+ CC_INSTRUCTION_OPCODE_EXT *Ext;\r
+ UINT64 EffectiveAddress;\r
+\r
+ Ext = &InstructionData->Ext;\r
+ EffectiveAddress = 0;\r
+\r
+ if (IsRipRelative (InstructionData)) {\r
+ //\r
+ // RIP-relative displacement is a 32-bit signed value\r
+ //\r
+ INT32 RipRelative;\r
+\r
+ RipRelative = *(INT32 *)InstructionData->Displacement;\r
+\r
+ UpdateForDisplacement (InstructionData, 4);\r
+\r
+ //\r
+ // Negative displacement is handled by standard UINT64 wrap-around.\r
+ //\r
+ return Regs->Rip + (UINT64)RipRelative;\r
+ }\r
+\r
+ switch (Ext->ModRm.Mod) {\r
+ case 1:\r
+ UpdateForDisplacement (InstructionData, 1);\r
+ EffectiveAddress += (UINT64)(*(INT8 *)(InstructionData->Displacement));\r
+ break;\r
+ case 2:\r
+ switch (InstructionData->AddrSize) {\r
+ case Size16Bits:\r
+ UpdateForDisplacement (InstructionData, 2);\r
+ EffectiveAddress += (UINT64)(*(INT16 *)(InstructionData->Displacement));\r
+ break;\r
+ default:\r
+ UpdateForDisplacement (InstructionData, 4);\r
+ EffectiveAddress += (UINT64)(*(INT32 *)(InstructionData->Displacement));\r
+ break;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ if (InstructionData->SibPresent) {\r
+ INT64 Displacement;\r
+\r
+ if (Ext->Sib.Index != 4) {\r
+ CopyMem (\r
+ &Displacement,\r
+ CcGetRegisterPointer (Regs, Ext->Sib.Index),\r
+ sizeof (Displacement)\r
+ );\r
+ Displacement *= (INT64)(1 << Ext->Sib.Scale);\r
+\r
+ //\r
+ // Negative displacement is handled by standard UINT64 wrap-around.\r
+ //\r
+ EffectiveAddress += (UINT64)Displacement;\r
+ }\r
+\r
+ if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) {\r
+ EffectiveAddress += *CcGetRegisterPointer (Regs, Ext->Sib.Base);\r
+ } else {\r
+ UpdateForDisplacement (InstructionData, 4);\r
+ EffectiveAddress += (UINT64)(*(INT32 *)(InstructionData->Displacement));\r
+ }\r
+ } else {\r
+ EffectiveAddress += *CcGetRegisterPointer (Regs, Ext->ModRm.Rm);\r
+ }\r
+\r
+ return EffectiveAddress;\r
+}\r
+\r
+/**\r
+ Decode a ModRM byte.\r
+\r
+ Examine the instruction parsing context to decode a ModRM byte and the SIB\r
+ byte, if present.\r
+\r
+ @param[in] Regs x64 processor context\r
+ @param[in, out] InstructionData Instruction parsing context\r
+\r
+**/\r
+VOID\r
+CcDecodeModRm (\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN OUT CC_INSTRUCTION_DATA *InstructionData\r
+ )\r
+{\r
+ CC_INSTRUCTION_OPCODE_EXT *Ext;\r
+ INSTRUCTION_REX_PREFIX *RexPrefix;\r
+ INSTRUCTION_MODRM *ModRm;\r
+ INSTRUCTION_SIB *Sib;\r
+\r
+ RexPrefix = &InstructionData->RexPrefix;\r
+ Ext = &InstructionData->Ext;\r
+ ModRm = &InstructionData->ModRm;\r
+ Sib = &InstructionData->Sib;\r
+\r
+ InstructionData->ModRmPresent = TRUE;\r
+ ModRm->Uint8 = *(InstructionData->End);\r
+\r
+ InstructionData->Displacement++;\r
+ InstructionData->Immediate++;\r
+ InstructionData->End++;\r
+\r
+ Ext->ModRm.Mod = ModRm->Bits.Mod;\r
+ Ext->ModRm.Reg = (RexPrefix->Bits.BitR << 3) | ModRm->Bits.Reg;\r
+ Ext->ModRm.Rm = (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm;\r
+\r
+ Ext->RegData = *CcGetRegisterPointer (Regs, Ext->ModRm.Reg);\r
+\r
+ if (Ext->ModRm.Mod == 3) {\r
+ Ext->RmData = *CcGetRegisterPointer (Regs, Ext->ModRm.Rm);\r
+ } else {\r
+ if (ModRm->Bits.Rm == 4) {\r
+ InstructionData->SibPresent = TRUE;\r
+ Sib->Uint8 = *(InstructionData->End);\r
+\r
+ InstructionData->Displacement++;\r
+ InstructionData->Immediate++;\r
+ InstructionData->End++;\r
+\r
+ Ext->Sib.Scale = Sib->Bits.Scale;\r
+ Ext->Sib.Index = (RexPrefix->Bits.BitX << 3) | Sib->Bits.Index;\r
+ Ext->Sib.Base = (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base;\r
+ }\r
+\r
+ Ext->RmData = GetEffectiveMemoryAddress (Regs, InstructionData);\r
+ }\r
+}\r
+\r
+/**\r
+ Decode instruction prefixes.\r
+\r
+ Parse the instruction data to track the instruction prefixes that have\r
+ been used.\r
+\r
+ @param[in] Regs x64 processor context\r
+ @param[in, out] InstructionData Instruction parsing context\r
+\r
+ @retval EFI_SUCCESS Successfully decode Prefixes\r
+ @retval Others Other error as indicated\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+DecodePrefixes (\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs,\r
+ IN OUT CC_INSTRUCTION_DATA *InstructionData\r
+ )\r
+{\r
+ CC_INSTRUCTION_MODE Mode;\r
+ CC_INSTRUCTION_SIZE ModeDataSize;\r
+ CC_INSTRUCTION_SIZE ModeAddrSize;\r
+ UINT8 *Byte;\r
+ UINT8 ParsedLength;\r
+\r
+ ParsedLength = 0;\r
+\r
+ //\r
+ // Always in 64-bit mode\r
+ //\r
+ Mode = LongMode64Bit;\r
+ ModeDataSize = Size32Bits;\r
+ ModeAddrSize = Size64Bits;\r
+\r
+ InstructionData->Mode = Mode;\r
+ InstructionData->DataSize = ModeDataSize;\r
+ InstructionData->AddrSize = ModeAddrSize;\r
+\r
+ InstructionData->Prefixes = InstructionData->Begin;\r
+\r
+ Byte = InstructionData->Prefixes;\r
+ for ( ; ParsedLength <= MAX_INSTRUCTION_LENGTH; Byte++, InstructionData->PrefixSize++, ParsedLength++) {\r
+ //\r
+ // Check the 0x40 to 0x4F range using an if statement here since some\r
+ // compilers don't like the "case 0x40 ... 0x4F:" syntax. This avoids\r
+ // 16 case statements below.\r
+ //\r
+ if ((*Byte >= REX_PREFIX_START) && (*Byte <= REX_PREFIX_STOP)) {\r
+ InstructionData->RexPrefix.Uint8 = *Byte;\r
+ if ((*Byte & REX_64BIT_OPERAND_SIZE_MASK) != 0) {\r
+ InstructionData->DataSize = Size64Bits;\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
+ switch (*Byte) {\r
+ case OVERRIDE_SEGMENT_CS:\r
+ case OVERRIDE_SEGMENT_DS:\r
+ case OVERRIDE_SEGMENT_ES:\r
+ case OVERRIDE_SEGMENT_SS:\r
+ if (Mode != LongMode64Bit) {\r
+ InstructionData->SegmentSpecified = TRUE;\r
+ InstructionData->Segment = (*Byte >> 3) & 3;\r
+ }\r
+\r
+ break;\r
+\r
+ case OVERRIDE_SEGMENT_FS:\r
+ case OVERRIDE_SEGMENT_GS:\r
+ InstructionData->SegmentSpecified = TRUE;\r
+ InstructionData->Segment = *Byte & 7;\r
+ break;\r
+\r
+ case OVERRIDE_OPERAND_SIZE:\r
+ if (InstructionData->RexPrefix.Uint8 == 0) {\r
+ InstructionData->DataSize =\r
+ (Mode == LongMode64Bit) ? Size16Bits :\r
+ (Mode == LongModeCompat32Bit) ? Size16Bits :\r
+ (Mode == LongModeCompat16Bit) ? Size32Bits : 0;\r
+ }\r
+\r
+ break;\r
+\r
+ case OVERRIDE_ADDRESS_SIZE:\r
+ InstructionData->AddrSize =\r
+ (Mode == LongMode64Bit) ? Size32Bits :\r
+ (Mode == LongModeCompat32Bit) ? Size16Bits :\r
+ (Mode == LongModeCompat16Bit) ? Size32Bits : 0;\r
+ break;\r
+\r
+ case LOCK_PREFIX:\r
+ break;\r
+\r
+ case REPZ_PREFIX:\r
+ InstructionData->RepMode = RepZ;\r
+ break;\r
+\r
+ case REPNZ_PREFIX:\r
+ InstructionData->RepMode = RepNZ;\r
+ break;\r
+\r
+ default:\r
+ InstructionData->OpCodes = Byte;\r
+ InstructionData->OpCodeSize = (*Byte == TWO_BYTE_OPCODE_ESCAPE) ? 2 : 1;\r
+\r
+ InstructionData->End = Byte + InstructionData->OpCodeSize;\r
+ InstructionData->Displacement = InstructionData->End;\r
+ InstructionData->Immediate = InstructionData->End;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_ABORTED;\r
+}\r
+\r
+/**\r
+ Determine instruction length\r
+\r
+ Return the total length of the parsed instruction.\r
+\r
+ @param[in] InstructionData Instruction parsing context\r
+\r
+ @return Length of parsed instruction\r
+\r
+**/\r
+UINT64\r
+CcInstructionLength (\r
+ IN CC_INSTRUCTION_DATA *InstructionData\r
+ )\r
+{\r
+ return (UINT64)(InstructionData->End - InstructionData->Begin);\r
+}\r
+\r
+/**\r
+ Initialize the instruction parsing context.\r
+\r
+ Initialize the instruction parsing context, which includes decoding the\r
+ instruction prefixes.\r
+\r
+ @param[in, out] InstructionData Instruction parsing context\r
+ @param[in] Ghcb Pointer to the Guest-Hypervisor Communication\r
+ Block\r
+ @param[in] Regs x64 processor context\r
+\r
+ @retval EFI_SUCCESS Successfully initialize InstructionData\r
+ @retval Others Other error as indicated\r
+**/\r
+EFI_STATUS\r
+CcInitInstructionData (\r
+ IN OUT CC_INSTRUCTION_DATA *InstructionData,\r
+ IN GHCB *Ghcb,\r
+ IN EFI_SYSTEM_CONTEXT_X64 *Regs\r
+ )\r
+{\r
+ SetMem (InstructionData, sizeof (*InstructionData), 0);\r
+ InstructionData->Ghcb = Ghcb;\r
+ InstructionData->Begin = (UINT8 *)Regs->Rip;\r
+ InstructionData->End = (UINT8 *)Regs->Rip;\r
+\r
+ return DecodePrefixes (Regs, InstructionData);\r
+}\r