From nobody Mon Feb 9 03:05:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+50953+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 157428045263677.41790357982472; Wed, 20 Nov 2019 12:07:32 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id B1UWYY1788612xTRHqsBob9h; Wed, 20 Nov 2019 12:07:32 -0800 X-Received: from NAM02-CY1-obe.outbound.protection.outlook.com (NAM02-CY1-obe.outbound.protection.outlook.com []) by mx.groups.io with SMTP id smtpd.web09.13473.1574280451106774991 for ; Wed, 20 Nov 2019 12:07:31 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iWtWZ+VztK4LKZonIHzJTCpRmOVXfqgszHAAFgAyEeGUDoM9ucf6p2VPL8mjyGh4mNCgbqtBv1yq2fVLnaI1xgC+pywyzf8PGqqgu6yeVskgMUiMZF6pQG6lgtKcMHtDSz93qtLew61n/0oQ3i29k53vwxY+IUdw+61rW4IJ+bDIuzmsoG4dhgI+TG+yKDhEGF0WoY6TlL/nsG19QzYnOwxaf2/XHVrZ2HP5G3czgrQHQX6b2FwA9kbDlAEmf8jABHV2jYa63hLXRVyAyucB/M3ALFiDNwpk1ZJnDDGmfWMNU4HIGyotQjfouts7pQUWRAvjfwCnjFndoycj5qTU8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=GP/K+b6Qk/GAQKtt4JbDaJGlucKzpWn0jEr58tyrt7U=; b=Ze+Qp6XHeCU7duUNpijL5ijws9WjSmf1WGOJDWsEIQ4qhxLCyI7bb33WzZd1T7QR43XbjFAAYCOv5b84/KDVDuO89dZX5BeJoippdl1sOcFdOB6l/P3lGU8MZBy8v3k3k197KxzsInaCBguaqUaSvlw82JX+41DREjEYEOROfRNtDitBT8NIOmZTPvz5IwU5BXR7u0xhl5pyyVhyoQWjqsyj52NG6f1v/rkjgCzcMnhiOGyM66MgiEYojbURapaqvx54XYwNQ+P75zeyr5p8FOqbcrfUDP31nadgYmtHPcbH/b+8LO7J009WY/AohMpHHf38cDVcksQ3ukiZ364zZQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none X-Received: from DM6PR12MB3163.namprd12.prod.outlook.com (20.179.71.154) by DM6PR12MB3675.namprd12.prod.outlook.com (10.255.76.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2451.28; Wed, 20 Nov 2019 20:07:30 +0000 X-Received: from DM6PR12MB3163.namprd12.prod.outlook.com ([fe80::dd0c:8e53:4913:8ef4]) by DM6PR12MB3163.namprd12.prod.outlook.com ([fe80::dd0c:8e53:4913:8ef4%5]) with mapi id 15.20.2451.031; Wed, 20 Nov 2019 20:07:30 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io Cc: Jordan Justen , Laszlo Ersek , Ard Biesheuvel , Michael D Kinney , Liming Gao , Eric Dong , Ray Ni , Brijesh Singh Subject: [edk2-devel] [RFC PATCH v3 13/43] UefiCpuPkg/CpuExceptionHandler: Add support for NPF NAE events (MMIO) Date: Wed, 20 Nov 2019 14:06:35 -0600 Message-Id: <099d821fe084410f0b38ced234dd7b5d10a8981a.1574280425.git.thomas.lendacky@amd.com> In-Reply-To: References: X-ClientProxiedBy: DM3PR12CA0087.namprd12.prod.outlook.com (2603:10b6:0:57::31) To DM6PR12MB3163.namprd12.prod.outlook.com (2603:10b6:5:15e::26) MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: a295ef4e-52d7-4ea5-955b-08d76df545a1 X-MS-TrafficTypeDiagnostic: DM6PR12MB3675: X-MS-Exchange-PUrlCount: 1 X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:7219; Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+50953+1787277+3901457@groups.io; helo=web01.groups.io; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info: /xObx8MQNSYUEytANebxc7I5ejSQd5CKVhRYp4ftZkv/bJjBLqbsPmXvy3/1Snf8W4Ssgt2CxIvx0i31EjyB9U3P6rmrwtwxgZbSxADlDjarzBm2mwzzWXw9NZyDP2MokJvEZaIwteFw9MqxHfZuMOZ7UpwKYgcBN/V3uL2pwGRuOdyIi+caiZiaurrzcpHcudu6W3eZIV59LIPbYbo0zbM+oPXELGQh5r2/a8Na9JUMleFIUOcA84j4uBtWQ3+ZAhaBjbAdRkcFKGwoxjmLmSsTpZwcuEV1G+YUoogBINHEw+zh+ryiQ9/jpAuTAOrlWtQuIYDapO99n+nCDy7iglKwANGeGWnrMI6f7mzzP8jJVJIMe4fiawde1LxEES8xCR9/1HDn6erl2gIsUDu1JcUx9d2JUGNRQwDgYrLJMMI01TZC3W2rMyFvxWVe2LNHN7jSOsR3nODK+w2CFI3/LaD2bUi9M/wePfpRwwmFtXQ= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: a295ef4e-52d7-4ea5-955b-08d76df545a1 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Nov 2019 20:07:30.0566 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: vEnRPkHiivs+bjzwJc8vGm3UIh7OJl57IDCr0eptUoE6i6b0jqL9HSbUEKzekn2wlSSb7p43eFkuk9FsxIfSBA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3675 Precedence: Bulk List-Unsubscribe: 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,thomas.lendacky@amd.com X-Gm-Message-State: THALQjXaumLl6OYsHu1cGzcbx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1574280452; bh=CjJHYCpzPP8405zSK+qOibZRM4u2T5RFwA3AcqluRqE=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=RoUCFGaOTm12HShFhuK+pHPOsWloUM5aI2KBd+v4ZpGo2fXdx7Kxi2VBgP86TmwDFhL IUtTbF3CdKCJ+ZGgb8FRgjXm5FU0Dg0dzAIJ7Pb65wNKYwwOg0iZjxDyyg1945CvAUSyd OXEp72AVOU4mBhIb+aZNgBZtNat+m5yWxWg= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2198 Under SEV-ES, a NPF intercept for an NPT entry with a reserved bit set generates a #VC exception. This condition is assumed to be an MMIO access. VMGEXIT must be used to allow the hypervisor to handle this intercept. Add support to construct the required GHCB values to support a NPF NAE event for MMIO. Parse the instruction that generated the #VC exception, setting the required register values in the GHCB and creating the proper SW_EXIT_INFO1, SW_EXITINFO2 and SW_SCRATCH values in the GHCB. Cc: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Signed-off-by: Tom Lendacky --- .../X64/AMDSevVcCommon.c | 308 +++++++++++++++++- 1 file changed, 306 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c= b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c index 578fee7deaad..d82121c3fa1c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/AMDSevVcCommon.c @@ -86,8 +86,8 @@ typedef struct { UINT8 Scale; } Sib; =20 - UINTN RegData; - UINTN RmData; + INTN RegData; + INTN RmData; } SEV_ES_INSTRUCTION_OPCODE_EXT; =20 typedef struct { @@ -159,6 +159,198 @@ GhcbSetRegValid ( Ghcb->SaveArea.ValidBitmap[RegIndex] |=3D (1 << RegBit); } =20 +STATIC +INT64 * +GetRegisterPointer ( + EFI_SYSTEM_CONTEXT_X64 *Regs, + UINT8 Register + ) +{ + UINT64 *Reg; + + switch (Register) { + case 0: + Reg =3D &Regs->Rax; + break; + case 1: + Reg =3D &Regs->Rcx; + break; + case 2: + Reg =3D &Regs->Rdx; + break; + case 3: + Reg =3D &Regs->Rbx; + break; + case 4: + Reg =3D &Regs->Rsp; + break; + case 5: + Reg =3D &Regs->Rbp; + break; + case 6: + Reg =3D &Regs->Rsi; + break; + case 7: + Reg =3D &Regs->Rdi; + break; + case 8: + Reg =3D &Regs->R8; + break; + case 9: + Reg =3D &Regs->R9; + break; + case 10: + Reg =3D &Regs->R10; + break; + case 11: + Reg =3D &Regs->R11; + break; + case 12: + Reg =3D &Regs->R12; + break; + case 13: + Reg =3D &Regs->R13; + break; + case 14: + Reg =3D &Regs->R14; + break; + case 15: + Reg =3D &Regs->R15; + break; + default: + Reg =3D NULL; + } + ASSERT (Reg !=3D NULL); + + return (INT64 *) Reg; +} + +STATIC +VOID +UpdateForDisplacement ( + SEV_ES_INSTRUCTION_DATA *InstructionData, + UINTN Size + ) +{ + InstructionData->DisplacementSize =3D Size; + InstructionData->Immediate +=3D Size; + InstructionData->End +=3D Size; +} + +STATIC +BOOLEAN +IsRipRelative ( + SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext =3D &InstructionData->Ext; + + return ((InstructionData =3D=3D LongMode64Bit) && + (Ext->ModRm.Mod =3D=3D 0) && + (Ext->ModRm.Rm =3D=3D 5) && + (InstructionData->SibPresent =3D=3D FALSE)); +} + +STATIC +UINTN +GetEffectiveMemoryAddress ( + EFI_SYSTEM_CONTEXT_X64 *Regs, + SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext =3D &InstructionData->Ext; + INTN EffectiveAddress =3D 0; + + if (IsRipRelative (InstructionData)) { + /* RIP-relative displacement is a 32-bit signed value */ + INT32 RipRelative =3D *(INT32 *) InstructionData->Displacement; + + UpdateForDisplacement (InstructionData, 4); + return (UINTN) ((INTN) Regs->Rip + RipRelative); + } + + switch (Ext->ModRm.Mod) { + case 1: + UpdateForDisplacement (InstructionData, 1); + EffectiveAddress +=3D (INT8) (*(INT8 *) (InstructionData->Displacement= )); + break; + case 2: + switch (InstructionData->AddrSize) { + case Size16Bits: + UpdateForDisplacement (InstructionData, 2); + EffectiveAddress +=3D (INT16) (*(INT16 *) (InstructionData->Displace= ment)); + break; + default: + UpdateForDisplacement (InstructionData, 4); + EffectiveAddress +=3D (INT32) (*(INT32 *) (InstructionData->Displace= ment)); + break; + } + break; + } + + if (InstructionData->SibPresent) { + if (Ext->Sib.Index !=3D 4) { + EffectiveAddress +=3D (*GetRegisterPointer (Regs, Ext->Sib.Index) <<= Ext->Sib.Scale); + } + + if ((Ext->Sib.Base !=3D 5) || Ext->ModRm.Mod) { + EffectiveAddress +=3D *GetRegisterPointer (Regs, Ext->Sib.Base); + } else { + UpdateForDisplacement (InstructionData, 4); + EffectiveAddress +=3D (INT32) (*(INT32 *) (InstructionData->Displace= ment)); + } + } else { + EffectiveAddress +=3D *GetRegisterPointer (Regs, Ext->ModRm.Rm); + } + + return (UINTN) EffectiveAddress; +} + +STATIC +VOID +DecodeModRm ( + EFI_SYSTEM_CONTEXT_X64 *Regs, + SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + SEV_ES_INSTRUCTION_REX_PREFIX *RexPrefix =3D &InstructionData->RexPrefi= x; + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext =3D &InstructionData->Ext; + SEV_ES_INSTRUCTION_MODRM *ModRm =3D &InstructionData->ModRm; + SEV_ES_INSTRUCTION_SIB *Sib =3D &InstructionData->Sib; + + InstructionData->ModRmPresent =3D TRUE; + ModRm->Uint8 =3D *(InstructionData->End); + + InstructionData->Displacement++; + InstructionData->Immediate++; + InstructionData->End++; + + Ext->ModRm.Mod =3D ModRm->Bits.Mod; + Ext->ModRm.Reg =3D (RexPrefix->Bits.R << 3) | ModRm->Bits.Reg; + Ext->ModRm.Rm =3D (RexPrefix->Bits.B << 3) | ModRm->Bits.Rm; + + Ext->RegData =3D *GetRegisterPointer (Regs, Ext->ModRm.Reg); + + if (Ext->ModRm.Mod =3D=3D 3) { + Ext->RmData =3D *GetRegisterPointer (Regs, Ext->ModRm.Rm); + } else { + if (ModRm->Bits.Rm =3D=3D 4) { + InstructionData->SibPresent =3D TRUE; + Sib->Uint8 =3D *(InstructionData->End); + + InstructionData->Displacement++; + InstructionData->Immediate++; + InstructionData->End++; + + Ext->Sib.Scale =3D Sib->Bits.Scale; + Ext->Sib.Index =3D (RexPrefix->Bits.X << 3) | Sib->Bits.Index; + Ext->Sib.Base =3D (RexPrefix->Bits.B << 3) | Sib->Bits.Base; + } + + Ext->RmData =3D GetEffectiveMemoryAddress (Regs, InstructionData); + } +} + STATIC VOID DecodePrefixes ( @@ -269,6 +461,114 @@ InitInstructionData ( DecodePrefixes (Regs, InstructionData); } =20 +STATIC +UINTN +MmioExit ( + GHCB *Ghcb, + EFI_SYSTEM_CONTEXT_X64 *Regs, + SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + UINT64 ExitInfo1, ExitInfo2; + UINTN Status; + UINTN Bytes; + INTN *Register; + + Bytes =3D 0; + + switch (*(InstructionData->OpCodes)) { + /* MMIO write */ + case 0x88: + Bytes =3D 1; + case 0x89: + DecodeModRm (Regs, InstructionData); + Bytes =3D (Bytes) ? 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??? */ + VmgExit (Ghcb, SvmExitUnsupported, SvmExitNpf, 0); + ASSERT (0); + } + + ExitInfo1 =3D InstructionData->Ext.RmData; + ExitInfo2 =3D Bytes; + CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes); + + Ghcb->SaveArea.SwScratch =3D (UINT64) Ghcb->SharedBuffer; + Status =3D VmgExit (Ghcb, SvmExitMmioWrite, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + break; + + case 0xC6: + Bytes =3D 1; + case 0xC7: + DecodeModRm (Regs, InstructionData); + Bytes =3D (Bytes) ? Bytes + : (InstructionData->DataSize =3D=3D Size16Bits) ? 2 + : (InstructionData->DataSize =3D=3D Size32Bits) ? 4 + : 0; + + InstructionData->ImmediateSize =3D Bytes; + InstructionData->End +=3D Bytes; + + ExitInfo1 =3D InstructionData->Ext.RmData; + ExitInfo2 =3D Bytes; + CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes); + + Ghcb->SaveArea.SwScratch =3D (UINT64) Ghcb->SharedBuffer; + Status =3D VmgExit (Ghcb, SvmExitMmioWrite, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + break; + + /* MMIO read */ + case 0x8A: + Bytes =3D 1; + case 0x8B: + DecodeModRm (Regs, InstructionData); + Bytes =3D (Bytes) ? 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??? */ + VmgExit (Ghcb, SvmExitUnsupported, SvmExitNpf, 0); + ASSERT (0); + } + + ExitInfo1 =3D InstructionData->Ext.RmData; + ExitInfo2 =3D Bytes; + + Ghcb->SaveArea.SwScratch =3D (UINT64) Ghcb->SharedBuffer; + Status =3D VmgExit (Ghcb, SvmExitMmioRead, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + + Register =3D GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg); + if (Bytes =3D=3D 4) { + /* Zero-extend for 32-bit operation */ + *Register =3D 0; + } + CopyMem (Register, Ghcb->SharedBuffer, Bytes); + break; + + default: + Status =3D GP_EXCEPTION; + ASSERT (0); + } + + return Status; +} + STATIC UINTN UnsupportedExit ( @@ -605,6 +905,10 @@ DoVcCommon ( NaeExit =3D MsrExit; break; =20 + case SvmExitNpf: + NaeExit =3D MmioExit; + break; + default: NaeExit =3D UnsupportedExit; } --=20 2.17.1 -=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 (#50953): https://edk2.groups.io/g/devel/message/50953 Mute This Topic: https://groups.io/mt/60973109/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-