/** @file
  X64 #VC Exception Handler functon.

  Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Base.h>
#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/LocalApicLib.h>
#include <Library/MemEncryptSevLib.h>
#include <Library/CcExitLib.h>
#include <Register/Amd/Msr.h>
#include <Register/Intel/Cpuid.h>
#include <IndustryStandard/InstructionParsing.h>

#include "CcExitVcHandler.h"
#include "CcInstruction.h"

//
// Non-automatic Exit function prototype
//
typedef
UINT64
(*NAE_EXIT) (
  GHCB                    *Ghcb,
  EFI_SYSTEM_CONTEXT_X64  *Regs,
  CC_INSTRUCTION_DATA     *InstructionData
  );

//
// SEV-SNP Cpuid table entry/function
//
typedef PACKED struct {
  UINT32    EaxIn;
  UINT32    EcxIn;
  UINT64    Unused;
  UINT64    Unused2;
  UINT32    Eax;
  UINT32    Ebx;
  UINT32    Ecx;
  UINT32    Edx;
  UINT64    Reserved;
} SEV_SNP_CPUID_FUNCTION;

//
// SEV-SNP Cpuid page format
//
typedef PACKED struct {
  UINT32                    Count;
  UINT32                    Reserved1;
  UINT64                    Reserved2;
  SEV_SNP_CPUID_FUNCTION    function[0];
} SEV_SNP_CPUID_INFO;

/**
  Report an unsupported event to the hypervisor

  Use the VMGEXIT support to report an unsupported event to the hypervisor.

  @param[in] Ghcb             Pointer to the Guest-Hypervisor Communication
                              Block
  @param[in] Regs             x64 processor context
  @param[in] InstructionData  Instruction parsing context

  @return                     New exception value to propagate

**/
STATIC
UINT64
UnsupportedExit (
  IN GHCB                    *Ghcb,
  IN EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  Status;

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_UNSUPPORTED, Regs->ExceptionData, 0);
  if (Status == 0) {
    GHCB_EVENT_INJECTION  Event;

    Event.Uint64          = 0;
    Event.Elements.Vector = GP_EXCEPTION;
    Event.Elements.Type   = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
    Event.Elements.Valid  = 1;

    Status = Event.Uint64;
  }

  return Status;
}

/**
  Validate that the MMIO memory access is not to encrypted memory.

  Examine the pagetable entry for the memory specified. MMIO should not be
  performed against encrypted memory. MMIO to the APIC page is always allowed.

  @param[in] Ghcb           Pointer to the Guest-Hypervisor Communication Block
  @param[in] MemoryAddress  Memory address to validate
  @param[in] MemoryLength   Memory length to validate

  @retval 0          Memory is not encrypted
  @return            New exception value to propogate

**/
STATIC
UINT64
ValidateMmioMemory (
  IN GHCB   *Ghcb,
  IN UINTN  MemoryAddress,
  IN UINTN  MemoryLength
  )
{
  MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE  State;
  GHCB_EVENT_INJECTION                 GpEvent;
  UINTN                                Address;

  //
  // Allow APIC accesses (which will have the encryption bit set during
  // SEC and PEI phases).
  //
  Address = MemoryAddress & ~(SIZE_4KB - 1);
  if (Address == GetLocalApicBaseAddress ()) {
    return 0;
  }

  State = MemEncryptSevGetAddressRangeState (
            0,
            MemoryAddress,
            MemoryLength
            );
  if (State == MemEncryptSevAddressRangeUnencrypted) {
    return 0;
  }

  //
  // Any state other than unencrypted is an error, issue a #GP.
  //
  DEBUG ((
    DEBUG_ERROR,
    "MMIO using encrypted memory: %lx\n",
    (UINT64)MemoryAddress
    ));
  GpEvent.Uint64          = 0;
  GpEvent.Elements.Vector = GP_EXCEPTION;
  GpEvent.Elements.Type   = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
  GpEvent.Elements.Valid  = 1;

  return GpEvent.Uint64;
}

/**
  Handle an MMIO event.

  Use the VMGEXIT instruction to handle either an MMIO read or an MMIO write.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in, out] InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
MmioExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN OUT CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  ExitInfo1, ExitInfo2, Status;
  UINTN   Bytes;
  UINT64  *Register;
  UINT8   OpCode, SignByte;
  UINTN   Address;

  Bytes = 0;

  OpCode = *(InstructionData->OpCodes);
  if (OpCode == TWO_BYTE_OPCODE_ESCAPE) {
    OpCode = *(InstructionData->OpCodes + 1);
  }

  switch (OpCode) {
    //
    // MMIO write (MOV reg/memX, regX)
    //
    case 0x88:
      Bytes = 1;
    //
    // fall through
    //
    case 0x89:
      CcDecodeModRm (Regs, InstructionData);
      Bytes = ((Bytes != 0) ? Bytes :
               (InstructionData->DataSize == Size16Bits) ? 2 :
               (InstructionData->DataSize == Size32Bits) ? 4 :
               (InstructionData->DataSize == Size64Bits) ? 8 :
               0);

      if (InstructionData->Ext.ModRm.Mod == 3) {
        //
        // NPF on two register operands???
        //
        return UnsupportedExit (Ghcb, Regs, InstructionData);
      }

      Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = InstructionData->Ext.RmData;
      ExitInfo2 = Bytes;
      CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes);

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      break;

    //
    // MMIO write (MOV moffsetX, aX)
    //
    case 0xA2:
      Bytes = 1;
    //
    // fall through
    //
    case 0xA3:
      Bytes = ((Bytes != 0) ? Bytes :
               (InstructionData->DataSize == Size16Bits) ? 2 :
               (InstructionData->DataSize == Size32Bits) ? 4 :
               (InstructionData->DataSize == Size64Bits) ? 8 :
               0);

      InstructionData->ImmediateSize = (UINTN)(1 << InstructionData->AddrSize);
      InstructionData->End          += InstructionData->ImmediateSize;

      //
      // This code is X64 only, so a possible 8-byte copy to a UINTN is ok.
      // Use a STATIC_ASSERT to be certain the code is being built as X64.
      //
      STATIC_ASSERT (
        sizeof (UINTN) == sizeof (UINT64),
        "sizeof (UINTN) != sizeof (UINT64), this file must be built as X64"
        );

      Address = 0;
      CopyMem (
        &Address,
        InstructionData->Immediate,
        InstructionData->ImmediateSize
        );

      Status = ValidateMmioMemory (Ghcb, Address, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = Address;
      ExitInfo2 = Bytes;
      CopyMem (Ghcb->SharedBuffer, &Regs->Rax, Bytes);

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      break;

    //
    // MMIO write (MOV reg/memX, immX)
    //
    case 0xC6:
      Bytes = 1;
    //
    // fall through
    //
    case 0xC7:
      CcDecodeModRm (Regs, InstructionData);
      Bytes = ((Bytes != 0) ? Bytes :
               (InstructionData->DataSize == Size16Bits) ? 2 :
               (InstructionData->DataSize == Size32Bits) ? 4 :
               0);

      InstructionData->ImmediateSize = Bytes;
      InstructionData->End          += Bytes;

      Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = InstructionData->Ext.RmData;
      ExitInfo2 = Bytes;
      CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes);

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      break;

    //
    // MMIO read (MOV regX, reg/memX)
    //
    case 0x8A:
      Bytes = 1;
    //
    // fall through
    //
    case 0x8B:
      CcDecodeModRm (Regs, InstructionData);
      Bytes = ((Bytes != 0) ? Bytes :
               (InstructionData->DataSize == Size16Bits) ? 2 :
               (InstructionData->DataSize == Size32Bits) ? 4 :
               (InstructionData->DataSize == Size64Bits) ? 8 :
               0);
      if (InstructionData->Ext.ModRm.Mod == 3) {
        //
        // NPF on two register operands???
        //
        return UnsupportedExit (Ghcb, Regs, InstructionData);
      }

      Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = InstructionData->Ext.RmData;
      ExitInfo2 = Bytes;

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      Register = CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
      if (Bytes == 4) {
        //
        // Zero-extend for 32-bit operation
        //
        *Register = 0;
      }

      CopyMem (Register, Ghcb->SharedBuffer, Bytes);
      break;

    //
    // MMIO read (MOV aX, moffsetX)
    //
    case 0xA0:
      Bytes = 1;
    //
    // fall through
    //
    case 0xA1:
      Bytes = ((Bytes != 0) ? Bytes :
               (InstructionData->DataSize == Size16Bits) ? 2 :
               (InstructionData->DataSize == Size32Bits) ? 4 :
               (InstructionData->DataSize == Size64Bits) ? 8 :
               0);

      InstructionData->ImmediateSize = (UINTN)(1 << InstructionData->AddrSize);
      InstructionData->End          += InstructionData->ImmediateSize;

      //
      // This code is X64 only, so a possible 8-byte copy to a UINTN is ok.
      // Use a STATIC_ASSERT to be certain the code is being built as X64.
      //
      STATIC_ASSERT (
        sizeof (UINTN) == sizeof (UINT64),
        "sizeof (UINTN) != sizeof (UINT64), this file must be built as X64"
        );

      Address = 0;
      CopyMem (
        &Address,
        InstructionData->Immediate,
        InstructionData->ImmediateSize
        );

      Status = ValidateMmioMemory (Ghcb, Address, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = Address;
      ExitInfo2 = Bytes;

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      if (Bytes == 4) {
        //
        // Zero-extend for 32-bit operation
        //
        Regs->Rax = 0;
      }

      CopyMem (&Regs->Rax, Ghcb->SharedBuffer, Bytes);
      break;

    //
    // MMIO read w/ zero-extension ((MOVZX regX, reg/memX)
    //
    case 0xB6:
      Bytes = 1;
    //
    // fall through
    //
    case 0xB7:
      CcDecodeModRm (Regs, InstructionData);
      Bytes = (Bytes != 0) ? Bytes : 2;

      Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = InstructionData->Ext.RmData;
      ExitInfo2 = Bytes;

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      Register = CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
      SetMem (Register, (UINTN)(1 << InstructionData->DataSize), 0);
      CopyMem (Register, Ghcb->SharedBuffer, Bytes);
      break;

    //
    // MMIO read w/ sign-extension (MOVSX regX, reg/memX)
    //
    case 0xBE:
      Bytes = 1;
    //
    // fall through
    //
    case 0xBF:
      CcDecodeModRm (Regs, InstructionData);
      Bytes = (Bytes != 0) ? Bytes : 2;

      Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
      if (Status != 0) {
        return Status;
      }

      ExitInfo1 = InstructionData->Ext.RmData;
      ExitInfo2 = Bytes;

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      if (Bytes == 1) {
        UINT8  *Data;

        Data     = (UINT8 *)Ghcb->SharedBuffer;
        SignByte = ((*Data & BIT7) != 0) ? 0xFF : 0x00;
      } else {
        UINT16  *Data;

        Data     = (UINT16 *)Ghcb->SharedBuffer;
        SignByte = ((*Data & BIT15) != 0) ? 0xFF : 0x00;
      }

      Register = CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
      SetMem (Register, (UINTN)(1 << InstructionData->DataSize), SignByte);
      CopyMem (Register, Ghcb->SharedBuffer, Bytes);
      break;

    default:
      DEBUG ((DEBUG_ERROR, "Invalid MMIO opcode (%x)\n", OpCode));
      Status = GP_EXCEPTION;
      ASSERT (FALSE);
  }

  return Status;
}

/**
  Handle a MWAIT event.

  Use the VMGEXIT instruction to handle a MWAIT event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
MwaitExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  CcDecodeModRm (Regs, InstructionData);

  Ghcb->SaveArea.Rax = Regs->Rax;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
  Ghcb->SaveArea.Rcx = Regs->Rcx;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);

  return CcExitVmgExit (Ghcb, SVM_EXIT_MWAIT, 0, 0);
}

/**
  Handle a MONITOR event.

  Use the VMGEXIT instruction to handle a MONITOR event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
MonitorExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  CcDecodeModRm (Regs, InstructionData);

  Ghcb->SaveArea.Rax = Regs->Rax;  // Identity mapped, so VA = PA
  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
  Ghcb->SaveArea.Rcx = Regs->Rcx;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);
  Ghcb->SaveArea.Rdx = Regs->Rdx;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRdx);

  return CcExitVmgExit (Ghcb, SVM_EXIT_MONITOR, 0, 0);
}

/**
  Handle a WBINVD event.

  Use the VMGEXIT instruction to handle a WBINVD event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
WbinvdExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  return CcExitVmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0);
}

/**
  Handle a RDTSCP event.

  Use the VMGEXIT instruction to handle a RDTSCP event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
RdtscpExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  Status;

  CcDecodeModRm (Regs, InstructionData);

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_RDTSCP, 0, 0);
  if (Status != 0) {
    return Status;
  }

  if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRcx) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRdx))
  {
    return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  Regs->Rax = Ghcb->SaveArea.Rax;
  Regs->Rcx = Ghcb->SaveArea.Rcx;
  Regs->Rdx = Ghcb->SaveArea.Rdx;

  return 0;
}

/**
  Handle a VMMCALL event.

  Use the VMGEXIT instruction to handle a VMMCALL event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
VmmCallExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  Status;

  CcDecodeModRm (Regs, InstructionData);

  Ghcb->SaveArea.Rax = Regs->Rax;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
  Ghcb->SaveArea.Cpl = (UINT8)(Regs->Cs & 0x3);
  CcExitVmgSetOffsetValid (Ghcb, GhcbCpl);

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_VMMCALL, 0, 0);
  if (Status != 0) {
    return Status;
  }

  if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
    return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  Regs->Rax = Ghcb->SaveArea.Rax;

  return 0;
}

/**
  Handle an MSR event.

  Use the VMGEXIT instruction to handle either a RDMSR or WRMSR event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
MsrExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  ExitInfo1, Status;

  ExitInfo1 = 0;

  switch (*(InstructionData->OpCodes + 1)) {
    case 0x30: // WRMSR
      ExitInfo1          = 1;
      Ghcb->SaveArea.Rax = Regs->Rax;
      CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
      Ghcb->SaveArea.Rdx = Regs->Rdx;
      CcExitVmgSetOffsetValid (Ghcb, GhcbRdx);
    //
    // fall through
    //
    case 0x32: // RDMSR
      Ghcb->SaveArea.Rcx = Regs->Rcx;
      CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);
      break;
    default:
      return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_MSR, ExitInfo1, 0);
  if (Status != 0) {
    return Status;
  }

  if (ExitInfo1 == 0) {
    if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax) ||
        !CcExitVmgIsOffsetValid (Ghcb, GhcbRdx))
    {
      return UnsupportedExit (Ghcb, Regs, InstructionData);
    }

    Regs->Rax = Ghcb->SaveArea.Rax;
    Regs->Rdx = Ghcb->SaveArea.Rdx;
  }

  return 0;
}

/**
  Build the IOIO event information.

  The IOIO event information identifies the type of IO operation to be performed
  by the hypervisor. Build this information based on the instruction data.

  @param[in]       Regs             x64 processor context
  @param[in, out]  InstructionData  Instruction parsing context

  @return                           IOIO event information value

**/
STATIC
UINT64
IoioExitInfo (
  IN     EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN OUT CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  ExitInfo;

  ExitInfo = 0;

  switch (*(InstructionData->OpCodes)) {
    //
    // INS opcodes
    //
    case 0x6C:
    case 0x6D:
      ExitInfo |= IOIO_TYPE_INS;
      ExitInfo |= IOIO_SEG_ES;
      ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
      break;

    //
    // OUTS opcodes
    //
    case 0x6E:
    case 0x6F:
      ExitInfo |= IOIO_TYPE_OUTS;
      ExitInfo |= IOIO_SEG_DS;
      ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
      break;

    //
    // IN immediate opcodes
    //
    case 0xE4:
    case 0xE5:
      InstructionData->ImmediateSize = 1;
      InstructionData->End++;
      ExitInfo |= IOIO_TYPE_IN;
      ExitInfo |= ((*(InstructionData->OpCodes + 1)) << 16);
      break;

    //
    // OUT immediate opcodes
    //
    case 0xE6:
    case 0xE7:
      InstructionData->ImmediateSize = 1;
      InstructionData->End++;
      ExitInfo |= IOIO_TYPE_OUT;
      ExitInfo |= ((*(InstructionData->OpCodes + 1)) << 16) | IOIO_TYPE_OUT;
      break;

    //
    // IN register opcodes
    //
    case 0xEC:
    case 0xED:
      ExitInfo |= IOIO_TYPE_IN;
      ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
      break;

    //
    // OUT register opcodes
    //
    case 0xEE:
    case 0xEF:
      ExitInfo |= IOIO_TYPE_OUT;
      ExitInfo |= ((Regs->Rdx & 0xffff) << 16);
      break;

    default:
      return 0;
  }

  switch (*(InstructionData->OpCodes)) {
    //
    // Single-byte opcodes
    //
    case 0x6C:
    case 0x6E:
    case 0xE4:
    case 0xE6:
    case 0xEC:
    case 0xEE:
      ExitInfo |= IOIO_DATA_8;
      break;

    //
    // Length determined by instruction parsing
    //
    default:
      ExitInfo |= (InstructionData->DataSize == Size16Bits) ? IOIO_DATA_16
                                                          : IOIO_DATA_32;
  }

  switch (InstructionData->AddrSize) {
    case Size16Bits:
      ExitInfo |= IOIO_ADDR_16;
      break;

    case Size32Bits:
      ExitInfo |= IOIO_ADDR_32;
      break;

    case Size64Bits:
      ExitInfo |= IOIO_ADDR_64;
      break;

    default:
      break;
  }

  if (InstructionData->RepMode != 0) {
    ExitInfo |= IOIO_REP;
  }

  return ExitInfo;
}

/**
  Handle an IOIO event.

  Use the VMGEXIT instruction to handle an IOIO event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
IoioExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64   ExitInfo1, ExitInfo2, Status;
  BOOLEAN  IsString;

  ExitInfo1 = IoioExitInfo (Regs, InstructionData);
  if (ExitInfo1 == 0) {
    return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  IsString = ((ExitInfo1 & IOIO_TYPE_STR) != 0) ? TRUE : FALSE;
  if (IsString) {
    UINTN  IoBytes, VmgExitBytes;
    UINTN  GhcbCount, OpCount;

    Status = 0;

    IoBytes   = IOIO_DATA_BYTES (ExitInfo1);
    GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes;

    OpCount = ((ExitInfo1 & IOIO_REP) != 0) ? Regs->Rcx : 1;
    while (OpCount != 0) {
      ExitInfo2    = MIN (OpCount, GhcbCount);
      VmgExitBytes = ExitInfo2 * IoBytes;

      if ((ExitInfo1 & IOIO_TYPE_IN) == 0) {
        CopyMem (Ghcb->SharedBuffer, (VOID *)Regs->Rsi, VmgExitBytes);
        Regs->Rsi += VmgExitBytes;
      }

      Ghcb->SaveArea.SwScratch = (UINT64)Ghcb->SharedBuffer;
      CcExitVmgSetOffsetValid (Ghcb, GhcbSwScratch);
      Status = CcExitVmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, ExitInfo2);
      if (Status != 0) {
        return Status;
      }

      if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
        CopyMem ((VOID *)Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes);
        Regs->Rdi += VmgExitBytes;
      }

      if ((ExitInfo1 & IOIO_REP) != 0) {
        Regs->Rcx -= ExitInfo2;
      }

      OpCount -= ExitInfo2;
    }
  } else {
    if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
      Ghcb->SaveArea.Rax = 0;
    } else {
      CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
    }

    CcExitVmgSetOffsetValid (Ghcb, GhcbRax);

    Status = CcExitVmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0);
    if (Status != 0) {
      return Status;
    }

    if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {
      if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax)) {
        return UnsupportedExit (Ghcb, Regs, InstructionData);
      }

      CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1));
    }
  }

  return 0;
}

/**
  Handle a INVD event.

  Use the VMGEXIT instruction to handle a INVD event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
InvdExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  return CcExitVmgExit (Ghcb, SVM_EXIT_INVD, 0, 0);
}

/**
  Fetch CPUID leaf/function via hypervisor/VMGEXIT.

  @param[in, out] Ghcb         Pointer to the Guest-Hypervisor Communication
                               Block
  @param[in]      EaxIn        EAX input for cpuid instruction
  @param[in]      EcxIn        ECX input for cpuid instruction
  @param[in]      Xcr0In       XCR0 at time of cpuid instruction
  @param[in, out] Eax          Pointer to store leaf's EAX value
  @param[in, out] Ebx          Pointer to store leaf's EBX value
  @param[in, out] Ecx          Pointer to store leaf's ECX value
  @param[in, out] Edx          Pointer to store leaf's EDX value
  @param[in, out] Status       Pointer to store status from VMGEXIT (always 0
                               unless return value indicates failure)
  @param[in, out] Unsupported  Pointer to store indication of unsupported
                               VMGEXIT (always false unless return value
                               indicates failure)

  @retval TRUE                 CPUID leaf fetch successfully.
  @retval FALSE                Error occurred while fetching CPUID leaf. Callers
                               should Status and Unsupported and handle
                               accordingly if they indicate a more precise
                               error condition.

**/
STATIC
BOOLEAN
GetCpuidHyp (
  IN OUT GHCB     *Ghcb,
  IN     UINT32   EaxIn,
  IN     UINT32   EcxIn,
  IN     UINT64   XCr0,
  IN OUT UINT32   *Eax,
  IN OUT UINT32   *Ebx,
  IN OUT UINT32   *Ecx,
  IN OUT UINT32   *Edx,
  IN OUT UINT64   *Status,
  IN OUT BOOLEAN  *UnsupportedExit
  )
{
  *UnsupportedExit   = FALSE;
  Ghcb->SaveArea.Rax = EaxIn;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);
  Ghcb->SaveArea.Rcx = EcxIn;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);
  if (EaxIn == CPUID_EXTENDED_STATE) {
    Ghcb->SaveArea.XCr0 = XCr0;
    CcExitVmgSetOffsetValid (Ghcb, GhcbXCr0);
  }

  *Status = CcExitVmgExit (Ghcb, SVM_EXIT_CPUID, 0, 0);
  if (*Status != 0) {
    return FALSE;
  }

  if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRbx) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRcx) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRdx))
  {
    *UnsupportedExit = TRUE;
    return FALSE;
  }

  if (Eax) {
    *Eax = (UINT32)(UINTN)Ghcb->SaveArea.Rax;
  }

  if (Ebx) {
    *Ebx = (UINT32)(UINTN)Ghcb->SaveArea.Rbx;
  }

  if (Ecx) {
    *Ecx = (UINT32)(UINTN)Ghcb->SaveArea.Rcx;
  }

  if (Edx) {
    *Edx = (UINT32)(UINTN)Ghcb->SaveArea.Rdx;
  }

  return TRUE;
}

/**
  Check if SEV-SNP enabled.

  @retval TRUE      SEV-SNP is enabled.
  @retval FALSE     SEV-SNP is disabled.

**/
STATIC
BOOLEAN
SnpEnabled (
  VOID
  )
{
  MSR_SEV_STATUS_REGISTER  Msr;

  Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);

  return !!Msr.Bits.SevSnpBit;
}

/**
  Calculate the total XSAVE area size for enabled XSAVE areas

  @param[in]      XFeaturesEnabled  Bit-mask of enabled XSAVE features/areas as
                                    indicated by XCR0/MSR_IA32_XSS bits
  @param[in, out] XSaveSize         Pointer to storage for calculated XSAVE area
                                    size
  @param[in]      Compacted         Whether or not the calculation is for the
                                    normal XSAVE area size (leaf 0xD,0x0,EBX) or
                                    compacted XSAVE area size (leaf 0xD,0x1,EBX)


  @retval TRUE                      XSAVE size calculation was successful.
  @retval FALSE                     XSAVE size calculation was unsuccessful.
**/
STATIC
BOOLEAN
GetCpuidXSaveSize (
  IN     UINT64   XFeaturesEnabled,
  IN OUT UINT32   *XSaveSize,
  IN     BOOLEAN  Compacted
  )
{
  SEV_SNP_CPUID_INFO  *CpuidInfo;
  UINT64              XFeaturesFound = 0;
  UINT32              Idx;

  //
  // The base/legacy XSave size is documented to be 0x240 in the APM.
  //
  *XSaveSize = 0x240;
  CpuidInfo  = (SEV_SNP_CPUID_INFO *)(UINT64)PcdGet32 (PcdOvmfCpuidBase);

  for (Idx = 0; Idx < CpuidInfo->Count; Idx++) {
    SEV_SNP_CPUID_FUNCTION  *CpuidFn = &CpuidInfo->function[Idx];

    if (!((CpuidFn->EaxIn == 0xD) && (CpuidFn->EcxIn > 1))) {
      continue;
    }

    if (XFeaturesFound & (1ULL << CpuidFn->EcxIn) ||
        !(XFeaturesEnabled & (1ULL << CpuidFn->EcxIn)))
    {
      continue;
    }

    XFeaturesFound |= (1ULL << CpuidFn->EcxIn);
    if (Compacted) {
      *XSaveSize += CpuidFn->Eax;
    } else {
      *XSaveSize = MAX (*XSaveSize, CpuidFn->Eax + CpuidFn->Ebx);
    }
  }

  /*
   * Either the guest set unsupported XCR0/XSS bits, or the corresponding
   * entries in the CPUID table were not present. This is an invalid state.
   */
  if (XFeaturesFound != (XFeaturesEnabled & ~3UL)) {
    return FALSE;
  }

  return TRUE;
}

/**
  Check if a CPUID leaf/function is indexed via ECX sub-leaf/sub-function

  @param[in]      EaxIn        EAX input for cpuid instruction

  @retval FALSE                cpuid leaf/function is not indexed by ECX input
  @retval TRUE                 cpuid leaf/function is indexed by ECX input

**/
STATIC
BOOLEAN
IsFunctionIndexed (
  IN     UINT32  EaxIn
  )
{
  switch (EaxIn) {
    case CPUID_CACHE_PARAMS:
    case CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS:
    case CPUID_EXTENDED_TOPOLOGY:
    case CPUID_EXTENDED_STATE:
    case CPUID_INTEL_RDT_MONITORING:
    case CPUID_INTEL_RDT_ALLOCATION:
    case CPUID_INTEL_SGX:
    case CPUID_INTEL_PROCESSOR_TRACE:
    case CPUID_DETERMINISTIC_ADDRESS_TRANSLATION_PARAMETERS:
    case CPUID_V2_EXTENDED_TOPOLOGY:
    case 0x8000001D: /* Cache Topology Information */
      return TRUE;
  }

  return FALSE;
}

/**
  Fetch CPUID leaf/function via SEV-SNP CPUID table.

  @param[in, out] Ghcb         Pointer to the Guest-Hypervisor Communication
                               Block
  @param[in]      EaxIn        EAX input for cpuid instruction
  @param[in]      EcxIn        ECX input for cpuid instruction
  @param[in]      Xcr0In       XCR0 at time of cpuid instruction
  @param[in, out] Eax          Pointer to store leaf's EAX value
  @param[in, out] Ebx          Pointer to store leaf's EBX value
  @param[in, out] Ecx          Pointer to store leaf's ECX value
  @param[in, out] Edx          Pointer to store leaf's EDX value
  @param[in, out] Status       Pointer to store status from VMGEXIT (always 0
                               unless return value indicates failure)
  @param[in, out] Unsupported  Pointer to store indication of unsupported
                               VMGEXIT (always false unless return value
                               indicates failure)

  @retval TRUE                 CPUID leaf fetch successfully.
  @retval FALSE                Error occurred while fetching CPUID leaf. Callers
                               should Status and Unsupported and handle
                               accordingly if they indicate a more precise
                               error condition.

**/
STATIC
BOOLEAN
GetCpuidFw (
  IN OUT GHCB     *Ghcb,
  IN     UINT32   EaxIn,
  IN     UINT32   EcxIn,
  IN     UINT64   XCr0,
  IN OUT UINT32   *Eax,
  IN OUT UINT32   *Ebx,
  IN OUT UINT32   *Ecx,
  IN OUT UINT32   *Edx,
  IN OUT UINT64   *Status,
  IN OUT BOOLEAN  *Unsupported
  )
{
  SEV_SNP_CPUID_INFO  *CpuidInfo;
  BOOLEAN             Found;
  UINT32              Idx;

  CpuidInfo = (SEV_SNP_CPUID_INFO *)(UINT64)PcdGet32 (PcdOvmfCpuidBase);
  Found     = FALSE;

  for (Idx = 0; Idx < CpuidInfo->Count; Idx++) {
    SEV_SNP_CPUID_FUNCTION  *CpuidFn = &CpuidInfo->function[Idx];

    if (CpuidFn->EaxIn != EaxIn) {
      continue;
    }

    if (IsFunctionIndexed (CpuidFn->EaxIn) && (CpuidFn->EcxIn != EcxIn)) {
      continue;
    }

    *Eax = CpuidFn->Eax;
    *Ebx = CpuidFn->Ebx;
    *Ecx = CpuidFn->Ecx;
    *Edx = CpuidFn->Edx;

    Found = TRUE;
    break;
  }

  if (!Found) {
    *Eax = *Ebx = *Ecx = *Edx = 0;
    goto Out;
  }

  if (EaxIn == CPUID_VERSION_INFO) {
    IA32_CR4  Cr4;
    UINT32    Ebx2;
    UINT32    Edx2;

    if (!GetCpuidHyp (
           Ghcb,
           EaxIn,
           EcxIn,
           XCr0,
           NULL,
           &Ebx2,
           NULL,
           &Edx2,
           Status,
           Unsupported
           ))
    {
      return FALSE;
    }

    /* initial APIC ID */
    *Ebx = (*Ebx & 0x00FFFFFF) | (Ebx2 & 0xFF000000);
    /* APIC enabled bit */
    *Edx = (*Edx & ~BIT9) | (Edx2 & BIT9);
    /* OSXSAVE enabled bit */
    Cr4.UintN = AsmReadCr4 ();
    *Ecx      = (Cr4.Bits.OSXSAVE) ? (*Ecx & ~BIT27) | (*Ecx & BIT27)
                              : (*Ecx & ~BIT27);
  } else if (EaxIn == CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) {
    IA32_CR4  Cr4;

    Cr4.UintN = AsmReadCr4 ();
    /* OSPKE enabled bit */
    *Ecx = (Cr4.Bits.PKE) ? (*Ecx | BIT4) : (*Ecx & ~BIT4);
  } else if (EaxIn == CPUID_EXTENDED_TOPOLOGY) {
    if (!GetCpuidHyp (
           Ghcb,
           EaxIn,
           EcxIn,
           XCr0,
           NULL,
           NULL,
           NULL,
           Edx,
           Status,
           Unsupported
           ))
    {
      return FALSE;
    }
  } else if ((EaxIn == CPUID_EXTENDED_STATE) && ((EcxIn == 0) || (EcxIn == 1))) {
    MSR_IA32_XSS_REGISTER  XssMsr;
    BOOLEAN                Compacted;
    UINT32                 XSaveSize;

    XssMsr.Uint64 = 0;
    Compacted     = FALSE;
    if (EcxIn == 1) {
      /*
       * The PPR and APM aren't clear on what size should be encoded in
       * 0xD:0x1:EBX when compaction is not enabled by either XSAVEC or
       * XSAVES, as these are generally fixed to 1 on real CPUs. Report
       * this undefined case as an error.
       */
      if (!(*Eax & (BIT3 | BIT1))) {
        /* (XSAVES | XSAVEC) */
        return FALSE;
      }

      Compacted     = TRUE;
      XssMsr.Uint64 = AsmReadMsr64 (MSR_IA32_XSS);
    }

    if (!GetCpuidXSaveSize (
           XCr0 | XssMsr.Uint64,
           &XSaveSize,
           Compacted
           ))
    {
      return FALSE;
    }

    *Ebx = XSaveSize;
  } else if (EaxIn == 0x8000001E) {
    UINT32  Ebx2;
    UINT32  Ecx2;

    /* extended APIC ID */
    if (!GetCpuidHyp (
           Ghcb,
           EaxIn,
           EcxIn,
           XCr0,
           Eax,
           &Ebx2,
           &Ecx2,
           NULL,
           Status,
           Unsupported
           ))
    {
      return FALSE;
    }

    /* compute ID */
    *Ebx = (*Ebx & 0xFFFFFF00) | (Ebx2 & 0x000000FF);
    /* node ID */
    *Ecx = (*Ecx & 0xFFFFFF00) | (Ecx2 & 0x000000FF);
  }

Out:
  *Status      = 0;
  *Unsupported = FALSE;
  return TRUE;
}

/**
  Handle a CPUID event.

  Use VMGEXIT instruction or CPUID table to handle a CPUID event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
CpuidExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  BOOLEAN  Unsupported;
  UINT64   Status;
  UINT32   EaxIn;
  UINT32   EcxIn;
  UINT64   XCr0;
  UINT32   Eax;
  UINT32   Ebx;
  UINT32   Ecx;
  UINT32   Edx;

  EaxIn = (UINT32)(UINTN)Regs->Rax;
  EcxIn = (UINT32)(UINTN)Regs->Rcx;

  if (EaxIn == CPUID_EXTENDED_STATE) {
    IA32_CR4  Cr4;

    Cr4.UintN           = AsmReadCr4 ();
    Ghcb->SaveArea.XCr0 = (Cr4.Bits.OSXSAVE == 1) ? AsmXGetBv (0) : 1;
    XCr0                = (Cr4.Bits.OSXSAVE == 1) ? AsmXGetBv (0) : 1;
  }

  if (SnpEnabled ()) {
    if (!GetCpuidFw (
           Ghcb,
           EaxIn,
           EcxIn,
           XCr0,
           &Eax,
           &Ebx,
           &Ecx,
           &Edx,
           &Status,
           &Unsupported
           ))
    {
      goto CpuidFail;
    }
  } else {
    if (!GetCpuidHyp (
           Ghcb,
           EaxIn,
           EcxIn,
           XCr0,
           &Eax,
           &Ebx,
           &Ecx,
           &Edx,
           &Status,
           &Unsupported
           ))
    {
      goto CpuidFail;
    }
  }

  Regs->Rax = Eax;
  Regs->Rbx = Ebx;
  Regs->Rcx = Ecx;
  Regs->Rdx = Edx;

  return 0;

CpuidFail:
  if (Unsupported) {
    return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  return Status;
}

/**
  Handle a RDPMC event.

  Use the VMGEXIT instruction to handle a RDPMC event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
RdpmcExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  Status;

  Ghcb->SaveArea.Rcx = Regs->Rcx;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRcx);

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_RDPMC, 0, 0);
  if (Status != 0) {
    return Status;
  }

  if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRdx))
  {
    return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  Regs->Rax = Ghcb->SaveArea.Rax;
  Regs->Rdx = Ghcb->SaveArea.Rdx;

  return 0;
}

/**
  Handle a RDTSC event.

  Use the VMGEXIT instruction to handle a RDTSC event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
RdtscExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  UINT64  Status;

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_RDTSC, 0, 0);
  if (Status != 0) {
    return Status;
  }

  if (!CcExitVmgIsOffsetValid (Ghcb, GhcbRax) ||
      !CcExitVmgIsOffsetValid (Ghcb, GhcbRdx))
  {
    return UnsupportedExit (Ghcb, Regs, InstructionData);
  }

  Regs->Rax = Ghcb->SaveArea.Rax;
  Regs->Rdx = Ghcb->SaveArea.Rdx;

  return 0;
}

/**
  Handle a DR7 register write event.

  Use the VMGEXIT instruction to handle a DR7 write event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully
  @return                          New exception value to propagate

**/
STATIC
UINT64
Dr7WriteExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  CC_INSTRUCTION_OPCODE_EXT  *Ext;
  SEV_ES_PER_CPU_DATA        *SevEsData;
  UINT64                     *Register;
  UINT64                     Status;

  Ext       = &InstructionData->Ext;
  SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);

  CcDecodeModRm (Regs, InstructionData);

  //
  // MOV DRn always treats MOD == 3 no matter how encoded
  //
  Register = CcGetRegisterPointer (Regs, Ext->ModRm.Rm);

  //
  // Using a value of 0 for ExitInfo1 means RAX holds the value
  //
  Ghcb->SaveArea.Rax = *Register;
  CcExitVmgSetOffsetValid (Ghcb, GhcbRax);

  Status = CcExitVmgExit (Ghcb, SVM_EXIT_DR7_WRITE, 0, 0);
  if (Status != 0) {
    return Status;
  }

  SevEsData->Dr7       = *Register;
  SevEsData->Dr7Cached = 1;

  return 0;
}

/**
  Handle a DR7 register read event.

  Use the VMGEXIT instruction to handle a DR7 read event.

  @param[in, out] Ghcb             Pointer to the Guest-Hypervisor Communication
                                   Block
  @param[in, out] Regs             x64 processor context
  @param[in]      InstructionData  Instruction parsing context

  @retval 0                        Event handled successfully

**/
STATIC
UINT64
Dr7ReadExit (
  IN OUT GHCB                    *Ghcb,
  IN OUT EFI_SYSTEM_CONTEXT_X64  *Regs,
  IN     CC_INSTRUCTION_DATA     *InstructionData
  )
{
  CC_INSTRUCTION_OPCODE_EXT  *Ext;
  SEV_ES_PER_CPU_DATA        *SevEsData;
  UINT64                     *Register;

  Ext       = &InstructionData->Ext;
  SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);

  CcDecodeModRm (Regs, InstructionData);

  //
  // MOV DRn always treats MOD == 3 no matter how encoded
  //
  Register = CcGetRegisterPointer (Regs, Ext->ModRm.Rm);

  //
  // If there is a cached valued for DR7, return that. Otherwise return the
  // DR7 standard reset value of 0x400 (no debug breakpoints set).
  //
  *Register = (SevEsData->Dr7Cached == 1) ? SevEsData->Dr7 : 0x400;

  return 0;
}

/**
  Handle a #VC exception.

  Performs the necessary processing to handle a #VC exception.

  @param[in, out]  Ghcb           Pointer to the GHCB
  @param[in, out]  ExceptionType  Pointer to an EFI_EXCEPTION_TYPE to be set
                                  as value to use on error.
  @param[in, out]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT

  @retval  EFI_SUCCESS            Exception handled
  @retval  EFI_UNSUPPORTED        #VC not supported, (new) exception value to
                                  propagate provided
  @retval  EFI_PROTOCOL_ERROR     #VC handling failed, (new) exception value to
                                  propagate provided

**/
EFI_STATUS
EFIAPI
InternalVmgExitHandleVc (
  IN OUT GHCB                *Ghcb,
  IN OUT EFI_EXCEPTION_TYPE  *ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT  SystemContext
  )
{
  EFI_SYSTEM_CONTEXT_X64  *Regs;
  NAE_EXIT                NaeExit;
  CC_INSTRUCTION_DATA     InstructionData;
  UINT64                  ExitCode, Status;
  EFI_STATUS              VcRet;
  BOOLEAN                 InterruptState;

  VcRet = EFI_SUCCESS;

  Regs = SystemContext.SystemContextX64;

  CcExitVmgInit (Ghcb, &InterruptState);

  ExitCode = Regs->ExceptionData;
  switch (ExitCode) {
    case SVM_EXIT_DR7_READ:
      NaeExit = Dr7ReadExit;
      break;

    case SVM_EXIT_DR7_WRITE:
      NaeExit = Dr7WriteExit;
      break;

    case SVM_EXIT_RDTSC:
      NaeExit = RdtscExit;
      break;

    case SVM_EXIT_RDPMC:
      NaeExit = RdpmcExit;
      break;

    case SVM_EXIT_CPUID:
      NaeExit = CpuidExit;
      break;

    case SVM_EXIT_INVD:
      NaeExit = InvdExit;
      break;

    case SVM_EXIT_IOIO_PROT:
      NaeExit = IoioExit;
      break;

    case SVM_EXIT_MSR:
      NaeExit = MsrExit;
      break;

    case SVM_EXIT_VMMCALL:
      NaeExit = VmmCallExit;
      break;

    case SVM_EXIT_RDTSCP:
      NaeExit = RdtscpExit;
      break;

    case SVM_EXIT_WBINVD:
      NaeExit = WbinvdExit;
      break;

    case SVM_EXIT_MONITOR:
      NaeExit = MonitorExit;
      break;

    case SVM_EXIT_MWAIT:
      NaeExit = MwaitExit;
      break;

    case SVM_EXIT_NPF:
      NaeExit = MmioExit;
      break;

    default:
      NaeExit = UnsupportedExit;
  }

  CcInitInstructionData (&InstructionData, Ghcb, Regs);

  Status = NaeExit (Ghcb, Regs, &InstructionData);
  if (Status == 0) {
    Regs->Rip += CcInstructionLength (&InstructionData);
  } else {
    GHCB_EVENT_INJECTION  Event;

    Event.Uint64 = Status;
    if (Event.Elements.ErrorCodeValid != 0) {
      Regs->ExceptionData = Event.Elements.ErrorCode;
    } else {
      Regs->ExceptionData = 0;
    }

    *ExceptionType = Event.Elements.Vector;

    VcRet = EFI_PROTOCOL_ERROR;
  }

  CcExitVmgDone (Ghcb, InterruptState);

  return VcRet;
}

/**
  Routine to allow ASSERT from within #VC.

  @param[in, out]  SevEsData  Pointer to the per-CPU data

**/
VOID
EFIAPI
VmgExitIssueAssert (
  IN OUT SEV_ES_PER_CPU_DATA  *SevEsData
  )
{
  //
  // Progress will be halted, so set VcCount to allow for ASSERT output
  // to be seen.
  //
  SevEsData->VcCount = 0;

  ASSERT (FALSE);
  CpuDeadLoop ();
}
