From nobody Mon Feb 9 14:34:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+98209+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+98209+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1673308595; cv=none; d=zohomail.com; s=zohoarc; b=YJ43Y4l0+P8dwlCwxWsxHNMtmbn5AYy4cvuyBlNUPndL/jGsk+7UZEyXY3r2SSfGVjabDzNK3ML+tsAV6eu1RqLfcy59FZqiKEqHbpdQ2pneobu/YfdNBgCVOkBW22XOSLTRJsEkmuyvXMkRTFEmSIGw/ZoShoZQAJk+RDhGknA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673308595; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=12SAy45/u2EUAqg00Ks6s0gRedzakKXaxDT/LP0bNTY=; b=NsV1yljpikmFzzj9HOiz/E1R3mUEjwK0kOrhnpwIr0OecU8y401Tkp16RwTSEu1+BfQmf3CoGmjonG8yIYrMHvTphj4FKrK0MuQ8FWRpWM5j3oo4TRR0ePmH8rhCvGEavmL4oD2qfM8kXhBblnzYjpFx1Ib1FoxZCmQ5giKRoD4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+98209+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1673308595363985.8824631759991; Mon, 9 Jan 2023 15:56:35 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id Uq0rYY1788612xYaqKe3BOqY; Mon, 09 Jan 2023 15:56:35 -0800 X-Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web11.90720.1673308590013112462 for ; Mon, 09 Jan 2023 15:56:34 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10585"; a="321715307" X-IronPort-AV: E=Sophos;i="5.96,313,1665471600"; d="scan'208";a="321715307" X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Jan 2023 15:56:33 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10585"; a="689221925" X-IronPort-AV: E=Sophos;i="5.96,313,1665471600"; d="scan'208";a="689221925" X-Received: from caij-mobl.ccr.corp.intel.com (HELO mxu9-mobl1.ccr.corp.intel.com) ([10.255.29.89]) by orsmga001-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Jan 2023 15:56:31 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min M Xu , Erdem Aktas , James Bottomley , Jiewen Yao , Gerd Hoffmann , Tom Lendacky , Ryan Afranji Subject: [edk2-devel] [PATCH V2 2/2] OvmfPkg/CcExitLib: Refactor TDX MmioExit Date: Tue, 10 Jan 2023 07:56:12 +0800 Message-Id: <20230109235612.439-3-min.m.xu@intel.com> In-Reply-To: <20230109235612.439-1-min.m.xu@intel.com> References: <20230109235612.439-1-min.m.xu@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: 9ECOmgDhnNhntZulgH7QQPwHx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1673308595; bh=PMzT7rz3MCST73W6piZ/Jm2epfHBIxCdP2z26BE5Opw=; h=Cc:Date:From:Reply-To:Subject:To; b=C2yvukftI9o4EEFN3vzfCOFwt1EwvjfbCVfRS8AWGWLByeZA7cGl7OMvHrISfgDxYiV dk2GTHpOFd3Cf4klWuGiU9pRSyxqpgIR3rXzDrZfzQP7E/YpYg10ZyFmSn/6DgojSOn7h Xos6eMVP8LDuWRxYvwS4u1VIEhHzbLmocTI= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1673308595590100009 Content-Type: text/plain; charset="utf-8" From: Min M Xu BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4169 The previous TDX MmioExit doesn't handle the Mmio instructions correctly in some scenarios. This patch refactors the implementation to fix the issues. Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Tom Lendacky Cc: Ryan Afranji Reported-by: Ryan Afranji Signed-off-by: Min Xu --- OvmfPkg/Library/CcExitLib/CcExitVeHandler.c | 525 ++++++++++++++------ 1 file changed, 363 insertions(+), 162 deletions(-) diff --git a/OvmfPkg/Library/CcExitLib/CcExitVeHandler.c b/OvmfPkg/Library/= CcExitLib/CcExitVeHandler.c index 30d547d5fe55..9a803cc38c84 100644 --- a/OvmfPkg/Library/CcExitLib/CcExitVeHandler.c +++ b/OvmfPkg/Library/CcExitLib/CcExitVeHandler.c @@ -13,6 +13,10 @@ #include #include #include +#include "CcInstruction.h" + +#define TDX_MMIO_READ 0 +#define TDX_MMIO_WRITE 1 =20 typedef union { struct { @@ -216,14 +220,15 @@ STATIC VOID EFIAPI TdxDecodeInstruction ( - IN UINT8 *Rip + IN UINT8 *Rip, + IN UINT32 Length ) { UINTN i; =20 DEBUG ((DEBUG_INFO, "TDX: #TD[EPT] instruction (%p):", Rip)); - for (i =3D 0; i < 15; i++) { - DEBUG ((DEBUG_INFO, "%02x:", Rip[i])); + for (i =3D 0; i < MIN (15, Length); i++) { + DEBUG ((DEBUG_INFO, "%02x ", Rip[i])); } =20 DEBUG ((DEBUG_INFO, "\n")); @@ -233,52 +238,326 @@ TdxDecodeInstruction ( if ((x)) { \ TdxDecodeInstruction(Rip); \ TdVmCall(TDVMCALL_HALT, 0, 0, 0, 0, 0); \ + CpuDeadLoop (); \ } =20 +/** + * Tdx MMIO access via TdVmcall. + * + * @param MmioSize Size of the MMIO access + * @param ReadOrWrite Read or write operation + * @param GuestPA Guest physical address + * @param Val Pointer to the value which is read or written + + * @retval EFI_SUCCESS Successfully access the mmio + * @retval Others Other errors as indicated + */ STATIC -UINT64 * -EFIAPI -GetRegFromContext ( - IN EFI_SYSTEM_CONTEXT_X64 *Regs, - IN UINTN RegIndex +EFI_STATUS +TdxMmioReadWrite ( + IN UINT32 MmioSize, + IN UINT32 ReadOrWrite, + IN UINT64 GuestPA, + IN UINT64 *Val ) { - switch (RegIndex) { - case 0: return &Regs->Rax; - break; - case 1: return &Regs->Rcx; - break; - case 2: return &Regs->Rdx; - break; - case 3: return &Regs->Rbx; - break; - case 4: return &Regs->Rsp; - break; - case 5: return &Regs->Rbp; - break; - case 6: return &Regs->Rsi; - break; - case 7: return &Regs->Rdi; - break; - case 8: return &Regs->R8; - break; - case 9: return &Regs->R9; + UINT64 TdStatus; + + if ((MmioSize !=3D 1) && (MmioSize !=3D 2) && (MmioSize !=3D 4) && (Mmio= Size !=3D 8)) { + return EFI_INVALID_PARAMETER; + } + + if (Val =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + TdStatus =3D 0; + if (ReadOrWrite =3D=3D TDX_MMIO_READ) { + TdStatus =3D TdVmCall (TDVMCALL_MMIO, MmioSize, TDX_MMIO_READ, GuestPA= , 0, Val); + } else if (ReadOrWrite =3D=3D TDX_MMIO_WRITE) { + TdStatus =3D TdVmCall (TDVMCALL_MMIO, MmioSize, TDX_MMIO_WRITE, GuestP= A, *Val, 0); + } else { + return EFI_INVALID_PARAMETER; + } + + if (TdStatus !=3D 0) { + DEBUG ((DEBUG_ERROR, "%a: TdVmcall failed with %llx\n", __FUNCTION__, = TdStatus)); + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +typedef struct { + UINT8 OpCode; + UINT32 Bytes; + EFI_PHYSICAL_ADDRESS Address; + UINT64 Val; + UINT64 *Register; + UINT32 ReadOrWrite; +} MMIO_EXIT_PARSED_INSTRUCTION; + +/** + * Parse the MMIO instructions. + * + * @param Regs Pointer to the EFI_SYSTEM_CONTEXT_X64 which in= cludes the instructions + * @param InstructionData Pointer to the CC_INSTRUCTION_DATA + * @param ParsedInstruction Pointer to the parsed instruction data + * + * @retval EFI_SUCCESS Successfully parsed the instructions + * @retval Others Other error as indicated + */ +STATIC +EFI_STATUS +ParseMmioExitInstructions ( + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, + IN OUT CC_INSTRUCTION_DATA *InstructionData, + OUT MMIO_EXIT_PARSED_INSTRUCTION *ParsedInstruction + ) +{ + EFI_STATUS Status; + UINT8 OpCode; + UINT8 SignByte; + UINT32 Bytes; + EFI_PHYSICAL_ADDRESS Address; + UINT64 Val; + UINT64 *Register; + UINT32 ReadOrWrite; + + Address =3D 0; + Bytes =3D 0; + Register =3D NULL; + Status =3D EFI_SUCCESS; + Val =3D 0; + + Status =3D CcInitInstructionData (InstructionData, NULL, Regs); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Initialize InstructionData failed! (%r)\n", = __FUNCTION__, Status)); + return Status; + } + + OpCode =3D *(InstructionData->OpCodes); + if (OpCode =3D=3D TWO_BYTE_OPCODE_ESCAPE) { + OpCode =3D *(InstructionData->OpCodes + 1); + } + + switch (OpCode) { + // + // MMIO write (MOV reg/memX, regX) + // + case 0x88: + Bytes =3D 1; + // + // fall through + // + case 0x89: + CcDecodeModRm (Regs, InstructionData); + Bytes =3D ((Bytes !=3D 0) ? Bytes : + (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : + (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : + (InstructionData->DataSize =3D=3D Size64Bits) ? 8 : + 0); + + if (InstructionData->Ext.ModRm.Mod =3D=3D 3) { + DEBUG ((DEBUG_ERROR, "%a: Parse Ext.ModRm.Mod error! (OpCode: 0x%x= )\n", __FUNCTION__, OpCode)); + return EFI_UNSUPPORTED; + } + + Address =3D InstructionData->Ext.RmData; + Val =3D InstructionData->Ext.RegData; + ReadOrWrite =3D TDX_MMIO_WRITE; + break; - case 10: return &Regs->R10; + + // + // MMIO write (MOV moffsetX, aX) + // + case 0xA2: + Bytes =3D 1; + // + // fall through + // + case 0xA3: + Bytes =3D ((Bytes !=3D 0) ? Bytes : + (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : + (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : + (InstructionData->DataSize =3D=3D Size64Bits) ? 8 : + 0); + + InstructionData->ImmediateSize =3D (UINTN)(1 << InstructionData->Add= rSize); + InstructionData->End +=3D InstructionData->ImmediateSize; + CopyMem (&Address, InstructionData->Immediate, InstructionData->Imme= diateSize); + + Val =3D Regs->Rax; + ReadOrWrite =3D TDX_MMIO_WRITE; break; - case 11: return &Regs->R11; + + // + // MMIO write (MOV reg/memX, immX) + // + case 0xC6: + Bytes =3D 1; + // + // fall through + // + case 0xC7: + CcDecodeModRm (Regs, InstructionData); + Bytes =3D ((Bytes !=3D 0) ? Bytes : + (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : + (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : + (InstructionData->DataSize =3D=3D Size64Bits) ? 8 : + 0); + + InstructionData->ImmediateSize =3D Bytes; + InstructionData->End +=3D Bytes; + + Val =3D 0; + CopyMem (&Val, InstructionData->Immediate, InstructionData->Immediat= eSize); + + Address =3D InstructionData->Ext.RmData; + ReadOrWrite =3D TDX_MMIO_WRITE; + break; - case 12: return &Regs->R12; + + // + // MMIO read (MOV regX, reg/memX) + // + case 0x8A: + Bytes =3D 1; + // + // fall through + // + case 0x8B: + CcDecodeModRm (Regs, InstructionData); + Bytes =3D ((Bytes !=3D 0) ? Bytes : + (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : + (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : + (InstructionData->DataSize =3D=3D Size64Bits) ? 8 : + 0); + if (InstructionData->Ext.ModRm.Mod =3D=3D 3) { + // + // NPF on two register operands??? + // + DEBUG ((DEBUG_ERROR, "%a: Parse Ext.ModRm.Mod error! (OpCode: 0x%x= )\n", __FUNCTION__, OpCode)); + return EFI_UNSUPPORTED; + } + + Address =3D InstructionData->Ext.RmData; + ReadOrWrite =3D TDX_MMIO_READ; + + Register =3D CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.= Reg); + if (Bytes =3D=3D 4) { + // + // Zero-extend for 32-bit operation + // + *Register =3D 0; + } + break; - case 13: return &Regs->R13; + + // + // MMIO read (MOV aX, moffsetX) + // + case 0xA0: + Bytes =3D 1; + // + // fall through + // + case 0xA1: + Bytes =3D ((Bytes !=3D 0) ? Bytes : + (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : + (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : + (InstructionData->DataSize =3D=3D Size64Bits) ? 8 : + 0); + + InstructionData->ImmediateSize =3D (UINTN)(1 << InstructionData->Add= rSize); + InstructionData->End +=3D InstructionData->ImmediateSize; + + Address =3D 0; + CopyMem ( + &Address, + InstructionData->Immediate, + InstructionData->ImmediateSize + ); + + if (Bytes =3D=3D 4) { + // + // Zero-extend for 32-bit operation + // + Regs->Rax =3D 0; + } + + Register =3D &Regs->Rax; + ReadOrWrite =3D TDX_MMIO_READ; + break; - case 14: return &Regs->R14; + + // + // MMIO read w/ zero-extension ((MOVZX regX, reg/memX) + // + case 0xB6: + Bytes =3D 1; + // + // fall through + // + case 0xB7: + CcDecodeModRm (Regs, InstructionData); + Bytes =3D (Bytes !=3D 0) ? Bytes : 2; + Address =3D InstructionData->Ext.RmData; + + Register =3D CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.= Reg); + SetMem (Register, (UINTN)(1 << InstructionData->DataSize), 0); + + ReadOrWrite =3D TDX_MMIO_READ; + break; - case 15: return &Regs->R15; + + // + // MMIO read w/ sign-extension (MOVSX regX, reg/memX) + // + case 0xBE: + Bytes =3D 1; + // + // fall through + // + case 0xBF: + CcDecodeModRm (Regs, InstructionData); + Bytes =3D (Bytes !=3D 0) ? Bytes : 2; + + Address =3D InstructionData->Ext.RmData; + + if (Bytes =3D=3D 1) { + UINT8 *Data; + Data =3D (UINT8 *)&Val; + SignByte =3D ((*Data & BIT7) !=3D 0) ? 0xFF : 0x00; + } else { + UINT16 *Data; + Data =3D (UINT16 *)&Val; + SignByte =3D ((*Data & BIT15) !=3D 0) ? 0xFF : 0x00; + } + + Register =3D CcGetRegisterPointer (Regs, InstructionData->Ext.ModRm.= Reg); + SetMem (Register, (UINTN)(1 << InstructionData->DataSize), SignByte); + + ReadOrWrite =3D TDX_MMIO_READ; + break; + + default: + DEBUG ((DEBUG_ERROR, "%a: Invalid MMIO opcode (%x)\n", __FUNCTION__,= OpCode)); + Status =3D EFI_UNSUPPORTED; + } + + if (!EFI_ERROR (Status)) { + ParsedInstruction->OpCode =3D OpCode; + ParsedInstruction->Address =3D Address; + ParsedInstruction->Bytes =3D Bytes; + ParsedInstruction->Register =3D Register; + ParsedInstruction->Val =3D Val; + ParsedInstruction->ReadOrWrite =3D ReadOrWrite; } =20 - return NULL; + return Status; } =20 /** @@ -290,160 +569,80 @@ GetRegFromContext ( @param[in] Veinfo VE Info =20 @retval 0 Event handled successfully - @return New exception value to propagate **/ STATIC -INTN +UINT64 EFIAPI MmioExit ( IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, IN TDCALL_VEINFO_RETURN_DATA *Veinfo ) { - UINT64 Status; - UINT32 MmioSize; - UINT32 RegSize; - UINT8 OpCode; - BOOLEAN SeenRex; - UINT64 *Reg; - UINT8 *Rip; - UINT64 Val; - UINT32 OpSize; - MODRM ModRm; - REX Rex; - TD_RETURN_DATA TdReturnData; - UINT8 Gpaw; - UINT64 TdSharedPageMask; + UINT64 TdStatus; + EFI_STATUS Status; + TD_RETURN_DATA TdReturnData; + UINT8 Gpaw; + UINT64 Val; + UINT64 TdSharedPageMask; + CC_INSTRUCTION_DATA InstructionData; + MMIO_EXIT_PARSED_INSTRUCTION ParsedInstruction; =20 - Rip =3D (UINT8 *)Regs->Rip; - Val =3D 0; - Rex.Val =3D 0; - SeenRex =3D FALSE; - - Status =3D TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData); - if (Status =3D=3D TDX_EXIT_REASON_SUCCESS) { + TdStatus =3D TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData); + if (TdStatus =3D=3D TDX_EXIT_REASON_SUCCESS) { Gpaw =3D (UINT8)(TdReturnData.TdInfo.Gpaw & 0x3f); TdSharedPageMask =3D 1ULL << (Gpaw - 1); } else { - DEBUG ((DEBUG_ERROR, "TDCALL failed with status=3D%llx\n", Status)); - return Status; + DEBUG ((DEBUG_ERROR, "%a: TDCALL failed with status=3D%llx\n", __FUNCT= ION__, TdStatus)); + goto FatalError; } =20 if ((Veinfo->GuestPA & TdSharedPageMask) =3D=3D 0) { - DEBUG ((DEBUG_ERROR, "EPT-violation #VE on private memory is not allow= ed!")); - TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); - CpuDeadLoop (); + DEBUG ((DEBUG_ERROR, "%a: EPT-violation #VE on private memory is not a= llowed!", __FUNCTION__)); + goto FatalError; } =20 - // - // Default to 32bit transfer - // - OpSize =3D 4; + Status =3D ParseMmioExitInstructions (Regs, &InstructionData, &ParsedIns= truction); + if (EFI_ERROR (Status)) { + goto FatalError; + } + + if (Veinfo->GuestPA !=3D (ParsedInstruction.Address | TdSharedPageMask))= { + DEBUG (( + DEBUG_ERROR, + "%a: Address is not correct! (%d: 0x%llx !=3D 0x%llx)\n", + __FUNCTION__, + ParsedInstruction.OpCode, + Veinfo->GuestPA, + ParsedInstruction.Address + )); + goto FatalError; + } =20 - do { - OpCode =3D *Rip++; - if (OpCode =3D=3D 0x66) { - OpSize =3D 2; - } else if ((OpCode =3D=3D 0x64) || (OpCode =3D=3D 0x65) || (OpCode =3D= =3D 0x67)) { - continue; - } else if ((OpCode >=3D 0x40) && (OpCode <=3D 0x4f)) { - SeenRex =3D TRUE; - Rex.Val =3D OpCode; - } else { - break; + if (ParsedInstruction.ReadOrWrite =3D=3D TDX_MMIO_WRITE ) { + Status =3D TdxMmioReadWrite (ParsedInstruction.Bytes, TDX_MMIO_WRITE, = Veinfo->GuestPA, &ParsedInstruction.Val); + } else { + Val =3D 0; + Status =3D TdxMmioReadWrite (ParsedInstruction.Bytes, TDX_MMIO_READ, V= einfo->GuestPA, &Val); + if (!EFI_ERROR (Status)) { + CopyMem (ParsedInstruction.Register, &Val, ParsedInstruction.Bytes); } - } while (TRUE); - - // - // We need to have at least 2 more bytes for this instruction - // - TDX_DECODER_BUG_ON (((UINT64)Rip - Regs->Rip) > 13); - - OpCode =3D *Rip++; - // - // Two-byte opecode, get next byte - // - if (OpCode =3D=3D 0x0F) { - OpCode =3D *Rip++; - } - - switch (OpCode) { - case 0x88: - case 0x8A: - case 0xB6: - MmioSize =3D 1; - break; - case 0xB7: - MmioSize =3D 2; - break; - default: - MmioSize =3D Rex.Bits.W ? 8 : OpSize; - break; - } - - /* Punt on AH/BH/CH/DH unless it shows up. */ - ModRm.Val =3D *Rip++; - TDX_DECODER_BUG_ON (MmioSize =3D=3D 1 && ModRm.Bits.Reg > 4 && !SeenRex = && OpCode !=3D 0xB6); - Reg =3D GetRegFromContext (Regs, ModRm.Bits.Reg | ((int)Rex.Bits.R << 3)= ); - TDX_DECODER_BUG_ON (!Reg); - - if (ModRm.Bits.Rm =3D=3D 4) { - ++Rip; /* SIB byte */ } =20 - if ((ModRm.Bits.Mod =3D=3D 2) || ((ModRm.Bits.Mod =3D=3D 0) && (ModRm.Bi= ts.Rm =3D=3D 5))) { - Rip +=3D 4; /* DISP32 */ - } else if (ModRm.Bits.Mod =3D=3D 1) { - ++Rip; /* DISP8 */ - } - - switch (OpCode) { - case 0x88: - case 0x89: - CopyMem ((void *)&Val, Reg, MmioSize); - Status =3D TdVmCall (TDVMCALL_MMIO, MmioSize, 1, Veinfo->GuestPA, Va= l, 0); - break; - case 0xC7: - CopyMem ((void *)&Val, Rip, OpSize); - Status =3D TdVmCall (TDVMCALL_MMIO, MmioSize, 1, Veinfo->GuestPA, Va= l, 0); - Rip +=3D OpSize; - default: - // - // 32-bit write registers are zero extended to the full register - // Hence 'MOVZX r[32/64], r/m16' is - // hardcoded to reg size 8, and the straight MOV case has a reg - // size of 8 in the 32-bit read case. - // - switch (OpCode) { - case 0xB6: - RegSize =3D Rex.Bits.W ? 8 : OpSize; - break; - case 0xB7: - RegSize =3D 8; - break; - default: - RegSize =3D MmioSize =3D=3D 4 ? 8 : MmioSize; - break; - } - - Status =3D TdVmCall (TDVMCALL_MMIO, MmioSize, 0, Veinfo->GuestPA, 0,= &Val); - if (Status =3D=3D 0) { - ZeroMem (Reg, RegSize); - CopyMem (Reg, (void *)&Val, MmioSize); - } - } - - if (Status =3D=3D 0) { - TDX_DECODER_BUG_ON (((UINT64)Rip - Regs->Rip) > 15); - + if (!EFI_ERROR (Status)) { // // We change instruction length to reflect true size so handler can // bump rip // - Veinfo->ExitInstructionLength =3D (UINT32)((UINT64)Rip - Regs->Rip); + Veinfo->ExitInstructionLength =3D (UINT32)(CcInstructionLength (&Inst= ructionData)); + TdxDecodeInstruction ((UINT8 *)Regs->Rip, Veinfo->ExitInstructionLengt= h); } =20 - return Status; + return 0; + +FatalError: + TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + CpuDeadLoop (); + return 0; } =20 /** @@ -479,6 +678,7 @@ CcExitHandleVe ( if (Status !=3D 0) { DEBUG ((DEBUG_ERROR, "#VE happened. TDGETVEINFO failed with Status =3D= 0x%llx\n", Status)); TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + CpuDeadLoop (); } =20 switch (ReturnData.VeInfo.ExitReason) { @@ -571,6 +771,7 @@ CcExitHandleVe ( )); =20 TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); + CpuDeadLoop (); } =20 SystemContext.SystemContextX64->Rip +=3D ReturnData.VeInfo.ExitInstructi= onLength; --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#98209): https://edk2.groups.io/g/devel/message/98209 Mute This Topic: https://groups.io/mt/96166748/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-