From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web11.9180.1672993477292899686 for ; Fri, 06 Jan 2023 00:24:37 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=JCt48Rtx; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: jiewen.yao@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1672993477; x=1704529477; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=INMTGXRRqmWOQEdqhBcQKu02zlAFg51KWpgUkQqkye4=; b=JCt48RtxqlPxSLXy8DKE+AodOS0i23SGp85dLEK4Q856TSIa9uhpPKmz ucTKUTOLMJAI5DY5xvqaepKPXqEqmxCNGrXVQbxJSM5KofvKQE2WKuHmK JV5O+tAtbgwFP498GfCJmov0K6OoQSPJC1Qdk8aBglqMShl/xBEaM6rt1 FHEVxKlK8lBI9BisClw2nNMJs/7+xGw4NbR52JGxEFWObWKDV49iFif1z ErYrsiXkosB8NlNO4DCm4EwrbbsriuVCVg/uDdwIzyyxLQXHTZMqbsLDs YDTzZVixlJoZVx1gifPpArf1JnvHFy1Hi9S0ERfmfqP48vsSEXs0rM4ZI Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10581"; a="324450658" X-IronPort-AV: E=Sophos;i="5.96,304,1665471600"; d="scan'208";a="324450658" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jan 2023 00:24:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10581"; a="605839989" X-IronPort-AV: E=Sophos;i="5.96,304,1665471600"; d="scan'208";a="605839989" Received: from fmsmsx602.amr.corp.intel.com ([10.18.126.82]) by orsmga003.jf.intel.com with ESMTP; 06 Jan 2023 00:24:34 -0800 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx602.amr.corp.intel.com (10.18.126.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Fri, 6 Jan 2023 00:24:34 -0800 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16 via Frontend Transport; Fri, 6 Jan 2023 00:24:34 -0800 Received: from NAM02-DM3-obe.outbound.protection.outlook.com (104.47.56.49) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.16; Fri, 6 Jan 2023 00:24:33 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=c31vhDVy6dcIR1mgMmHFTh+2AIL6DbUdCy6E0E0fUun3TCpaYGKbqc4RQlwNVZupcXTJV6KIvu6vEwDPVOEduQiEkRS24uKhOAocG9WpHuian4OEWNPXXyVkNp0Luhj5950QQYo72vbnB70ZIZgdp1xScjvFXh5D/3w5n6mRUiNQhZBai61i9lFXONnc0U1KpIHCE8ho4DHW09tqv1vsF98Arom/7xc7AOQq5O10nTxERlAIF28LsLSfhbKRv6XqFjfhrLq15RKwpjh664XmsVszTIBLLsKwI+o1kDsTWEvGMPBtqcoHStJRIgcr/4X9gd9WE/Y/+lWHBqnj1xg1Lw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=u8FIbnAgKfMSaP+UdpQuHat6g6L3ndq1Sdv3383yCK8=; b=fKPCJO52dTJ6369FqjXGipz0FSzXFZVUjaPBzBCmnMDAFw3TlB7x+0p5G37oCPcmpIWxjmCJjYFHgMxchdz8xKg2LEpFRy5QpNLqfx+Rzaz4UY397HMYi6bm4czzn3TElBNWQoDZ3ZEINREGZccwllhOiv5+Z4sUBm0y9S6+aE/zEl/+EakIgHOW96Qtl0Ecqrm+F7U+Gl0qGt++BnaoTDZpuTEZyZ2AVThLyESo85HQUDI5p9+wMeXpdgdSpc+BizMw8y9+RPpj6PVugQz0l7Ukzj1kutWNeMD8OE0UfuLAYCUU9x71TR+ijCxpt8EXP6XhfyK0zxiaA0ObesxNnQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from MW4PR11MB5872.namprd11.prod.outlook.com (2603:10b6:303:169::14) by CH0PR11MB5508.namprd11.prod.outlook.com (2603:10b6:610:d7::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5944.19; Fri, 6 Jan 2023 08:24:31 +0000 Received: from MW4PR11MB5872.namprd11.prod.outlook.com ([fe80::5f56:1bdc:2eae:c041]) by MW4PR11MB5872.namprd11.prod.outlook.com ([fe80::5f56:1bdc:2eae:c041%9]) with mapi id 15.20.5944.019; Fri, 6 Jan 2023 08:24:31 +0000 From: "Yao, Jiewen" To: "Xu, Min M" , "devel@edk2.groups.io" CC: Gerd Hoffmann , "Aktas, Erdem" , James Bottomley , Tom Lendacky Subject: Re: [PATCH V1 1/2] OvmfPkg/CcExitLib: Move common X86 instruction code to separate file Thread-Topic: [PATCH V1 1/2] OvmfPkg/CcExitLib: Move common X86 instruction code to separate file Thread-Index: AQHZG2O4sinxa5s5lk2uQTf6hsOnya6RGcKg Date: Fri, 6 Jan 2023 08:24:31 +0000 Message-ID: References: <20221229085548.476-1-min.m.xu@intel.com> <20221229085548.476-2-min.m.xu@intel.com> In-Reply-To: <20221229085548.476-2-min.m.xu@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MW4PR11MB5872:EE_|CH0PR11MB5508:EE_ x-ms-office365-filtering-correlation-id: a197c38c-57c9-4bba-f254-08daefbf6f40 x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: uGrZXRIDB86FOAu010j5QkXFf2B7tpIBxfE1fsBPDpAtsmr1c0gulVouu440eZTgS5oo/YATVfQ1XLY6jCPib03gwxTJoMyNZAJrY8L5AUdEBFshJTbsoH9TUr1b3KVMRMFLmTYJ1yNQ1eOb7YC+FH1GlXVuD1o7fHirK4PU8/Zay3LjHMF6W4rUG9PDFasUSq3hP4Z1bC6ma2B0CfsEe8IV6Lc7myxmi7dWeLhOQ4/YOJtuAaOFaAVsUJlctHZvxMbkr6lrcXDIdMfmGhyo9hh4wBouYdBNaIYtPmcTj2w+h3lFtwQGtZko5UNhMfs7hX5c3+PLbDQmcXl4Np1WzMsPTqPPCIXIqb0avDGbB1ILHy9HA5LuxExuRkJA2cCv5zu1AI9gxgPbUoglS2265bDnzqbAT3r7un/M/Bi+Tc1I2B1qRw6DuzMcD0lhMkhCogyCgKeqKcVkOkmZSXGIWGbTZKe1RnJWaMnt1eSEXHzyN2sOhfcVSDyMGSUcivI2WdG1k5OBlnoHT4mMNMJkva8Fta1oFJeMPNA+DbFhU5qAsPj5vCF40/X813C64h183jF1KTMzF4u7hHmpcLr8mo3+fSsg3PMVA4JxTherEy//eG9s0LyEL6oslhk6n/HrOj7y7MLr9PFPpg5y8LOWBB+7IcfGolykq37ykIujZcDOcyHE+pSfzK67hhTtT5zVTO0JqLn3U/IlTrC4JrCsumHeMdhfuCP+V7uSgzRm/zo= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW4PR11MB5872.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(6029001)(136003)(39860400002)(396003)(376002)(366004)(346002)(451199015)(66556008)(66946007)(52536014)(64756008)(4326008)(66446008)(76116006)(66476007)(41300700001)(54906003)(5660300002)(19627235002)(30864003)(8676002)(8936002)(2906002)(316002)(9686003)(71200400001)(53546011)(966005)(478600001)(6506007)(26005)(7696005)(86362001)(83380400001)(33656002)(186003)(110136005)(82960400001)(55016003)(38070700005)(122000001)(38100700002)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?2UeAa2vE/p3Mjk3m4LITWu1W0YunIxV4HmJf/NAbPqIjRzbe/+d7HnPkFkpJ?= =?us-ascii?Q?nerJVLaSRMXhtOK03i9P63YHy1BtBlQQynqpE5dSeTQLkKGW/Mumbe8u8rG3?= =?us-ascii?Q?aBqanJgLEdLGd4XK0bHtd0X/EIHzDOQrN3cTe3YMnDxvz6kPaL7lddrP3fOO?= =?us-ascii?Q?d5w/VCDSPlcqazNqaWLSCN47hwmOC6exbJBBCaq/aiiP1LpfjAIIf1Om+roq?= =?us-ascii?Q?NKuhzaaOZgtwL0FQCLR7OeEHVnIK8oqWBJqyf43sGqLPN0icqAyxCve/AGao?= =?us-ascii?Q?Q51VG3FP7wB9S6z20FO6/0+ls7vPweYZZxGtV+6sNre532Zgj2oRz/njF/os?= =?us-ascii?Q?H/xjkB7Sej7vghd+mJ/ibKTYWEfMTJ2tXvfnJEDIyoXg0XveLWXUyqineo6F?= =?us-ascii?Q?yIjUTMQ6nVvGByAQk/1k7yzeVlRZpPHPR6S2KYX0zfRQYCw62qaxZ8kywMFG?= =?us-ascii?Q?zzTjVBh0dHBAXAfr4yJmC+kBUq5ptWFigNxC8ByR1GPTIHH95ROut5k3WWo9?= =?us-ascii?Q?PkH5mq2BNZgGwBj4lmqW4MLyadj2R57Xm1vw10mZ+vSAulhIRK0EQYZe7DV7?= =?us-ascii?Q?6jgFs9xfwwvPM4Ws3oXjF3YcoLrCj9kMkUb2G+1RdrseRRjgNvoe+MYDkIJL?= =?us-ascii?Q?rV0gv5+FH8WXt38CxWlvyQhMPuHp70b4ODxjY2I8b9b8uEP6LWahXzxBxE6p?= =?us-ascii?Q?bYUAljqo6LMFt688yOvkciHwEwvZ7DvphBQpYdV6rfMPfXexcWfPRwnWWJzw?= =?us-ascii?Q?9sHlBS48s2Jb2EY27J3woGlyC2hAsEwcxZjGrwQJyNAVZ041WPqqY+s1V5jf?= =?us-ascii?Q?+yw7CSWFNXpbfhqbnqvXPVsjEZeIBuE5HZWna73AQw22QPxXI5gvvlGyzzql?= =?us-ascii?Q?P1S+JX3MWaDYxS3xDgR9OiqO2kCDe+J8FXeOMwXZLPUwDnXG4XYVgb+qx6rJ?= =?us-ascii?Q?WS2Oghc/fBgbIoA1yRTMzZ/kTIUNnl9iFJGR6/V44rfhS24TjtI2qxYjMLnm?= =?us-ascii?Q?LAYp32+g++X4Kod8sHrh792G8haw5fx8SgzuwG99SmjShSA9+C17elP33kpt?= =?us-ascii?Q?p+Ewd7yYeG4NaAHWucE7cmv6gyDxiIh5bajq+eqFfaytpa6UEfJqWlvpBhz9?= =?us-ascii?Q?Q7c8ha3taA7/lENIx1zniaHyCDHr14+DWU3h3FM+iYJLKzL4ZM6L6wmih4Kr?= =?us-ascii?Q?ABjB7ND5WtIBgK6g52cVEAuTymoNiMb8UB90rAp1bz/TPrMtLhziqj1mtW6z?= =?us-ascii?Q?ghngxSUdLQJunT88jn6iCigqfntYTsLSA808MxXeCvbTQlSlICWukofY7hdb?= =?us-ascii?Q?4tAk9VqWv36c9Wp1A81XIXX0rG+ZKJ1sfxbrLtoTNwmhklaOmCbpiOinU9CK?= =?us-ascii?Q?RNc5CI+OhpfYb2D7F4+tOAnGhBrffK9aye6h6ldjxLoy2nq7JZ2A5zUYugKZ?= =?us-ascii?Q?7fWYLvxOzcemuURQ5AIiO/BbnKjhMZ+ZXsYVfi3Kx0VerWqNpB49PtzAN2Zw?= =?us-ascii?Q?0iGesoSk1pI0m5NBTFyhYfmIDN9VfFA8azHopR8Ikh/2pSI4gJR5x6c1eGFa?= =?us-ascii?Q?ntYhAQMiUfcjqy140i4KbHoSzkcVF0gFd1qjuk2H?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MW4PR11MB5872.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: a197c38c-57c9-4bba-f254-08daefbf6f40 X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Jan 2023 08:24:31.0509 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Zhizwtz0aBtnD/duLJCNrwfo+tWtZnwysvpMC8vVgw2pOhiJn2UJ8/RrxM/1tpB1EyrZEbnHQQN2asVo0vJigQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH0PR11MB5508 Return-Path: jiewen.yao@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Jiewen Yao > -----Original Message----- > From: Xu, Min M > Sent: Thursday, December 29, 2022 4:56 PM > To: devel@edk2.groups.io > Cc: Xu, Min M ; Gerd Hoffmann > ; Aktas, Erdem ; James > Bottomley ; Yao, Jiewen ; Tom > Lendacky > Subject: [PATCH V1 1/2] OvmfPkg/CcExitLib: Move common X86 instruction > code to separate file >=20 > From: Min M Xu >=20 > https://bugzilla.tianocore.org/show_bug.cgi?id=3D4169 >=20 > Move common X86 instruction codes from CcExitVcHandler.c to separate > files (CcInstruction.h / CcInstruction.c) so that these codes can be > re-used in TDX. >=20 > Cc: Gerd Hoffmann > Cc: Erdem Aktas > Cc: James Bottomley > Cc: Jiewen Yao > Cc: Tom Lendacky > Signed-off-by: Min Xu > --- > OvmfPkg/Library/CcExitLib/CcExitLib.inf | 1 + > OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 697 +++----------------- > OvmfPkg/Library/CcExitLib/CcInstruction.c | 454 +++++++++++++ > OvmfPkg/Library/CcExitLib/CcInstruction.h | 197 ++++++ > OvmfPkg/Library/CcExitLib/SecCcExitLib.inf | 1 + > 5 files changed, 735 insertions(+), 615 deletions(-) > create mode 100644 OvmfPkg/Library/CcExitLib/CcInstruction.c > create mode 100644 OvmfPkg/Library/CcExitLib/CcInstruction.h >=20 > diff --git a/OvmfPkg/Library/CcExitLib/CcExitLib.inf > b/OvmfPkg/Library/CcExitLib/CcExitLib.inf > index 131fa6267522..bc75cd5f5a04 100644 > --- a/OvmfPkg/Library/CcExitLib/CcExitLib.inf > +++ b/OvmfPkg/Library/CcExitLib/CcExitLib.inf > @@ -25,6 +25,7 @@ > CcExitLib.c > CcExitVcHandler.c > CcExitVcHandler.h > + CcInstruction.c > PeiDxeCcExitVcHandler.c > CcExitVeHandler.c > X64/TdVmcallCpuid.nasm > diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c > b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c > index 985e5479775c..7fe11c53249e 100644 > --- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c > +++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c > @@ -17,107 +17,7 @@ > #include >=20 > #include "CcExitVcHandler.h" > - > -// > -// Instruction execution mode definition > -// > -typedef enum { > - LongMode64Bit =3D 0, > - LongModeCompat32Bit, > - LongModeCompat16Bit, > -} SEV_ES_INSTRUCTION_MODE; > - > -// > -// Instruction size definition (for operand and address) > -// > -typedef enum { > - Size8Bits =3D 0, > - Size16Bits, > - Size32Bits, > - Size64Bits, > -} SEV_ES_INSTRUCTION_SIZE; > - > -// > -// Intruction segment definition > -// > -typedef enum { > - SegmentEs =3D 0, > - SegmentCs, > - SegmentSs, > - SegmentDs, > - SegmentFs, > - SegmentGs, > -} SEV_ES_INSTRUCTION_SEGMENT; > - > -// > -// Instruction rep function definition > -// > -typedef enum { > - RepNone =3D 0, > - RepZ, > - RepNZ, > -} SEV_ES_INSTRUCTION_REP; > - > -typedef struct { > - UINT8 Rm; > - UINT8 Reg; > - UINT8 Mod; > -} SEV_ES_INSTRUCTION_MODRM_EXT; > - > -typedef struct { > - UINT8 Base; > - UINT8 Index; > - UINT8 Scale; > -} SEV_ES_INSTRUCTION_SIB_EXT; > - > -// > -// Instruction opcode definition > -// > -typedef struct { > - SEV_ES_INSTRUCTION_MODRM_EXT ModRm; > - > - SEV_ES_INSTRUCTION_SIB_EXT Sib; > - > - UINTN RegData; > - UINTN RmData; > -} SEV_ES_INSTRUCTION_OPCODE_EXT; > - > -// > -// Instruction parsing context definition > -// > -typedef struct { > - GHCB *Ghcb; > - > - SEV_ES_INSTRUCTION_MODE Mode; > - SEV_ES_INSTRUCTION_SIZE DataSize; > - SEV_ES_INSTRUCTION_SIZE AddrSize; > - BOOLEAN SegmentSpecified; > - SEV_ES_INSTRUCTION_SEGMENT Segment; > - SEV_ES_INSTRUCTION_REP RepMode; > - > - UINT8 *Begin; > - UINT8 *End; > - > - UINT8 *Prefixes; > - UINT8 *OpCodes; > - UINT8 *Displacement; > - UINT8 *Immediate; > - > - INSTRUCTION_REX_PREFIX RexPrefix; > - > - BOOLEAN ModRmPresent; > - INSTRUCTION_MODRM ModRm; > - > - BOOLEAN SibPresent; > - INSTRUCTION_SIB Sib; > - > - UINTN PrefixSize; > - UINTN OpCodeSize; > - UINTN DisplacementSize; > - UINTN ImmediateSize; > - > - SEV_ES_INSTRUCTION_OPCODE_EXT Ext; > -} SEV_ES_INSTRUCTION_DATA; > +#include "CcInstruction.h" >=20 > // > // Non-automatic Exit function prototype > @@ -125,9 +25,9 @@ typedef struct { > typedef > UINT64 > (*NAE_EXIT) ( > - GHCB *Ghcb, > - EFI_SYSTEM_CONTEXT_X64 *Regs, > - SEV_ES_INSTRUCTION_DATA *InstructionData > + GHCB *Ghcb, > + EFI_SYSTEM_CONTEXT_X64 *Regs, > + CC_INSTRUCTION_DATA *InstructionData > ); >=20 > // > @@ -155,439 +55,6 @@ typedef PACKED struct { > SEV_SNP_CPUID_FUNCTION function[0]; > } SEV_SNP_CPUID_INFO; >=20 > -/** > - Return a pointer to the contents of the specified register. > - > - Based upon the input register, return a pointer to the registers conte= nts > - in the x86 processor context. > - > - @param[in] Regs x64 processor context > - @param[in] Register Register to obtain pointer for > - > - @return Pointer to the contents of the requested register > - > -**/ > -STATIC > -UINT64 * > -GetRegisterPointer ( > - IN EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN 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 Reg; > -} > - > -/** > - Update the instruction parsing context for displacement bytes. > - > - @param[in, out] InstructionData Instruction parsing context > - @param[in] Size The instruction displacement size > - > -**/ > -STATIC > -VOID > -UpdateForDisplacement ( > - IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData, > - IN UINTN Size > - ) > -{ > - InstructionData->DisplacementSize =3D Size; > - InstructionData->Immediate +=3D Size; > - InstructionData->End +=3D Size; > -} > - > -/** > - Determine if an instruction address if RIP relative. > - > - Examine the instruction parsing context to determine if the address of= fset > - is relative to the instruction pointer. > - > - @param[in] InstructionData Instruction parsing context > - > - @retval TRUE Instruction addressing is RIP relative > - @retval FALSE Instruction addressing is not RIP relative > - > -**/ > -STATIC > -BOOLEAN > -IsRipRelative ( > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > - ) > -{ > - SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; > - > - Ext =3D &InstructionData->Ext; > - > - return ((InstructionData->Mode =3D=3D LongMode64Bit) && > - (Ext->ModRm.Mod =3D=3D 0) && > - (Ext->ModRm.Rm =3D=3D 5) && > - (InstructionData->SibPresent =3D=3D FALSE)); > -} > - > -/** > - Return the effective address of a memory operand. > - > - Examine the instruction parsing context to obtain the effective memory > - address of a memory operand. > - > - @param[in] Regs x64 processor context > - @param[in] InstructionData Instruction parsing context > - > - @return The memory operand effective address > - > -**/ > -STATIC > -UINT64 > -GetEffectiveMemoryAddress ( > - IN EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > - ) > -{ > - SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; > - UINT64 EffectiveAddress; > - > - Ext =3D &InstructionData->Ext; > - EffectiveAddress =3D 0; > - > - if (IsRipRelative (InstructionData)) { > - // > - // RIP-relative displacement is a 32-bit signed value > - // > - INT32 RipRelative; > - > - RipRelative =3D *(INT32 *)InstructionData->Displacement; > - > - UpdateForDisplacement (InstructionData, 4); > - > - // > - // Negative displacement is handled by standard UINT64 wrap-around. > - // > - return Regs->Rip + (UINT64)RipRelative; > - } > - > - switch (Ext->ModRm.Mod) { > - case 1: > - UpdateForDisplacement (InstructionData, 1); > - EffectiveAddress +=3D (UINT64)(*(INT8 *)(InstructionData->Displace= ment)); > - break; > - case 2: > - switch (InstructionData->AddrSize) { > - case Size16Bits: > - UpdateForDisplacement (InstructionData, 2); > - EffectiveAddress +=3D (UINT64)(*(INT16 *)(InstructionData- > >Displacement)); > - break; > - default: > - UpdateForDisplacement (InstructionData, 4); > - EffectiveAddress +=3D (UINT64)(*(INT32 *)(InstructionData- > >Displacement)); > - break; > - } > - > - break; > - } > - > - if (InstructionData->SibPresent) { > - INT64 Displacement; > - > - if (Ext->Sib.Index !=3D 4) { > - CopyMem ( > - &Displacement, > - GetRegisterPointer (Regs, Ext->Sib.Index), > - sizeof (Displacement) > - ); > - Displacement *=3D (INT64)(1 << Ext->Sib.Scale); > - > - // > - // Negative displacement is handled by standard UINT64 wrap-around= . > - // > - EffectiveAddress +=3D (UINT64)Displacement; > - } > - > - if ((Ext->Sib.Base !=3D 5) || Ext->ModRm.Mod) { > - EffectiveAddress +=3D *GetRegisterPointer (Regs, Ext->Sib.Base); > - } else { > - UpdateForDisplacement (InstructionData, 4); > - EffectiveAddress +=3D (UINT64)(*(INT32 *)(InstructionData- > >Displacement)); > - } > - } else { > - EffectiveAddress +=3D *GetRegisterPointer (Regs, Ext->ModRm.Rm); > - } > - > - return EffectiveAddress; > -} > - > -/** > - Decode a ModRM byte. > - > - Examine the instruction parsing context to decode a ModRM byte and the > SIB > - byte, if present. > - > - @param[in] Regs x64 processor context > - @param[in, out] InstructionData Instruction parsing context > - > -**/ > -STATIC > -VOID > -DecodeModRm ( > - IN EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData > - ) > -{ > - SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; > - INSTRUCTION_REX_PREFIX *RexPrefix; > - INSTRUCTION_MODRM *ModRm; > - INSTRUCTION_SIB *Sib; > - > - RexPrefix =3D &InstructionData->RexPrefix; > - Ext =3D &InstructionData->Ext; > - ModRm =3D &InstructionData->ModRm; > - 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.BitR << 3) | ModRm->Bits.Reg; > - Ext->ModRm.Rm =3D (RexPrefix->Bits.BitB << 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.BitX << 3) | Sib->Bits.Index; > - Ext->Sib.Base =3D (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base; > - } > - > - Ext->RmData =3D GetEffectiveMemoryAddress (Regs, InstructionData); > - } > -} > - > -/** > - Decode instruction prefixes. > - > - Parse the instruction data to track the instruction prefixes that have > - been used. > - > - @param[in] Regs x64 processor context > - @param[in, out] InstructionData Instruction parsing context > - > -**/ > -STATIC > -VOID > -DecodePrefixes ( > - IN EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData > - ) > -{ > - SEV_ES_INSTRUCTION_MODE Mode; > - SEV_ES_INSTRUCTION_SIZE ModeDataSize; > - SEV_ES_INSTRUCTION_SIZE ModeAddrSize; > - UINT8 *Byte; > - > - // > - // Always in 64-bit mode > - // > - Mode =3D LongMode64Bit; > - ModeDataSize =3D Size32Bits; > - ModeAddrSize =3D Size64Bits; > - > - InstructionData->Mode =3D Mode; > - InstructionData->DataSize =3D ModeDataSize; > - InstructionData->AddrSize =3D ModeAddrSize; > - > - InstructionData->Prefixes =3D InstructionData->Begin; > - > - Byte =3D InstructionData->Prefixes; > - for ( ; ; Byte++, InstructionData->PrefixSize++) { > - // > - // Check the 0x40 to 0x4F range using an if statement here since som= e > - // compilers don't like the "case 0x40 ... 0x4F:" syntax. This avoid= s > - // 16 case statements below. > - // > - if ((*Byte >=3D REX_PREFIX_START) && (*Byte <=3D REX_PREFIX_STOP)) { > - InstructionData->RexPrefix.Uint8 =3D *Byte; > - if ((*Byte & REX_64BIT_OPERAND_SIZE_MASK) !=3D 0) { > - InstructionData->DataSize =3D Size64Bits; > - } > - > - continue; > - } > - > - switch (*Byte) { > - case OVERRIDE_SEGMENT_CS: > - case OVERRIDE_SEGMENT_DS: > - case OVERRIDE_SEGMENT_ES: > - case OVERRIDE_SEGMENT_SS: > - if (Mode !=3D LongMode64Bit) { > - InstructionData->SegmentSpecified =3D TRUE; > - InstructionData->Segment =3D (*Byte >> 3) & 3; > - } > - > - break; > - > - case OVERRIDE_SEGMENT_FS: > - case OVERRIDE_SEGMENT_GS: > - InstructionData->SegmentSpecified =3D TRUE; > - InstructionData->Segment =3D *Byte & 7; > - break; > - > - case OVERRIDE_OPERAND_SIZE: > - if (InstructionData->RexPrefix.Uint8 =3D=3D 0) { > - InstructionData->DataSize =3D > - (Mode =3D=3D LongMode64Bit) ? Size16Bits : > - (Mode =3D=3D LongModeCompat32Bit) ? Size16Bits : > - (Mode =3D=3D LongModeCompat16Bit) ? Size32Bits : 0; > - } > - > - break; > - > - case OVERRIDE_ADDRESS_SIZE: > - InstructionData->AddrSize =3D > - (Mode =3D=3D LongMode64Bit) ? Size32Bits : > - (Mode =3D=3D LongModeCompat32Bit) ? Size16Bits : > - (Mode =3D=3D LongModeCompat16Bit) ? Size32Bits : 0; > - break; > - > - case LOCK_PREFIX: > - break; > - > - case REPZ_PREFIX: > - InstructionData->RepMode =3D RepZ; > - break; > - > - case REPNZ_PREFIX: > - InstructionData->RepMode =3D RepNZ; > - break; > - > - default: > - InstructionData->OpCodes =3D Byte; > - InstructionData->OpCodeSize =3D (*Byte =3D=3D > TWO_BYTE_OPCODE_ESCAPE) ? 2 : 1; > - > - InstructionData->End =3D Byte + InstructionData->OpCode= Size; > - InstructionData->Displacement =3D InstructionData->End; > - InstructionData->Immediate =3D InstructionData->End; > - return; > - } > - } > -} > - > -/** > - Determine instruction length > - > - Return the total length of the parsed instruction. > - > - @param[in] InstructionData Instruction parsing context > - > - @return Length of parsed instruction > - > -**/ > -STATIC > -UINT64 > -InstructionLength ( > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > - ) > -{ > - return (UINT64)(InstructionData->End - InstructionData->Begin); > -} > - > -/** > - Initialize the instruction parsing context. > - > - Initialize the instruction parsing context, which includes decoding th= e > - instruction prefixes. > - > - @param[in, out] InstructionData Instruction parsing context > - @param[in] Ghcb Pointer to the Guest-Hypervisor > Communication > - Block > - @param[in] Regs x64 processor context > - > -**/ > -STATIC > -VOID > -InitInstructionData ( > - IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData, > - IN GHCB *Ghcb, > - IN EFI_SYSTEM_CONTEXT_X64 *Regs > - ) > -{ > - SetMem (InstructionData, sizeof (*InstructionData), 0); > - InstructionData->Ghcb =3D Ghcb; > - InstructionData->Begin =3D (UINT8 *)Regs->Rip; > - InstructionData->End =3D (UINT8 *)Regs->Rip; > - > - DecodePrefixes (Regs, InstructionData); > -} > - > /** > Report an unsupported event to the hypervisor >=20 > @@ -604,9 +71,9 @@ InitInstructionData ( > STATIC > UINT64 > UnsupportedExit ( > - IN GHCB *Ghcb, > - IN EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN GHCB *Ghcb, > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 Status; > @@ -703,9 +170,9 @@ ValidateMmioMemory ( > STATIC > UINT64 > MmioExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN OUT CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 ExitInfo1, ExitInfo2, Status; > @@ -731,7 +198,7 @@ MmioExit ( > // fall through > // > case 0x89: > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); > Bytes =3D ((Bytes !=3D 0) ? Bytes : > (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : > (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : > @@ -824,7 +291,7 @@ MmioExit ( > // fall through > // > case 0xC7: > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); > Bytes =3D ((Bytes !=3D 0) ? Bytes : > (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : > (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : > @@ -860,7 +327,7 @@ MmioExit ( > // fall through > // > case 0x8B: > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); > Bytes =3D ((Bytes !=3D 0) ? Bytes : > (InstructionData->DataSize =3D=3D Size16Bits) ? 2 : > (InstructionData->DataSize =3D=3D Size32Bits) ? 4 : > @@ -888,7 +355,7 @@ MmioExit ( > return Status; > } >=20 > - Register =3D GetRegisterPointer (Regs, InstructionData->Ext.ModRm.= Reg); > + Register =3D CcGetRegisterPointer (Regs, InstructionData->Ext.ModR= m.Reg); > if (Bytes =3D=3D 4) { > // > // Zero-extend for 32-bit operation > @@ -967,7 +434,7 @@ MmioExit ( > // fall through > // > case 0xB7: > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); > Bytes =3D (Bytes !=3D 0) ? Bytes : 2; >=20 > Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, > Bytes); > @@ -985,7 +452,7 @@ MmioExit ( > return Status; > } >=20 > - Register =3D GetRegisterPointer (Regs, InstructionData->Ext.ModRm.= Reg); > + Register =3D CcGetRegisterPointer (Regs, InstructionData->Ext.ModR= m.Reg); > SetMem (Register, (UINTN)(1 << InstructionData->DataSize), 0); > CopyMem (Register, Ghcb->SharedBuffer, Bytes); > break; > @@ -999,7 +466,7 @@ MmioExit ( > // fall through > // > case 0xBF: > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); > Bytes =3D (Bytes !=3D 0) ? Bytes : 2; >=20 > Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, > Bytes); > @@ -1029,7 +496,7 @@ MmioExit ( > SignByte =3D ((*Data & BIT15) !=3D 0) ? 0xFF : 0x00; > } >=20 > - Register =3D GetRegisterPointer (Regs, InstructionData->Ext.ModRm.= Reg); > + Register =3D CcGetRegisterPointer (Regs, InstructionData->Ext.ModR= m.Reg); > SetMem (Register, (UINTN)(1 << InstructionData->DataSize), SignByt= e); > CopyMem (Register, Ghcb->SharedBuffer, Bytes); > break; > @@ -1060,12 +527,12 @@ MmioExit ( > STATIC > UINT64 > MwaitExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); >=20 > Ghcb->SaveArea.Rax =3D Regs->Rax; > CcExitVmgSetOffsetValid (Ghcb, GhcbRax); > @@ -1092,12 +559,12 @@ MwaitExit ( > STATIC > UINT64 > MonitorExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); >=20 > Ghcb->SaveArea.Rax =3D Regs->Rax; // Identity mapped, so VA =3D PA > CcExitVmgSetOffsetValid (Ghcb, GhcbRax); > @@ -1126,9 +593,9 @@ MonitorExit ( > STATIC > UINT64 > WbinvdExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > return CcExitVmgExit (Ghcb, SVM_EXIT_WBINVD, 0, 0); > @@ -1151,14 +618,14 @@ WbinvdExit ( > STATIC > UINT64 > RdtscpExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 Status; >=20 > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); >=20 > Status =3D CcExitVmgExit (Ghcb, SVM_EXIT_RDTSCP, 0, 0); > if (Status !=3D 0) { > @@ -1196,14 +663,14 @@ RdtscpExit ( > STATIC > UINT64 > VmmCallExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 Status; >=20 > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); >=20 > Ghcb->SaveArea.Rax =3D Regs->Rax; > CcExitVmgSetOffsetValid (Ghcb, GhcbRax); > @@ -1241,9 +708,9 @@ VmmCallExit ( > STATIC > UINT64 > MsrExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 ExitInfo1, Status; > @@ -1302,8 +769,8 @@ MsrExit ( > STATIC > UINT64 > IoioExitInfo ( > - IN EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN OUT CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 ExitInfo; > @@ -1437,9 +904,9 @@ IoioExitInfo ( > STATIC > UINT64 > IoioExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 ExitInfo1, ExitInfo2, Status; > @@ -1531,9 +998,9 @@ IoioExit ( > STATIC > UINT64 > InvdExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > return CcExitVmgExit (Ghcb, SVM_EXIT_INVD, 0, 0); > @@ -1949,9 +1416,9 @@ Out: > STATIC > UINT64 > CpuidExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > BOOLEAN Unsupported; > @@ -2041,9 +1508,9 @@ CpuidFail: > STATIC > UINT64 > RdpmcExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 Status; > @@ -2085,9 +1552,9 @@ RdpmcExit ( > STATIC > UINT64 > RdtscExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > UINT64 Status; > @@ -2126,25 +1593,25 @@ RdtscExit ( > STATIC > UINT64 > Dr7WriteExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > - SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; > - SEV_ES_PER_CPU_DATA *SevEsData; > - UINT64 *Register; > - UINT64 Status; > + CC_INSTRUCTION_OPCODE_EXT *Ext; > + SEV_ES_PER_CPU_DATA *SevEsData; > + UINT64 *Register; > + UINT64 Status; >=20 > Ext =3D &InstructionData->Ext; > SevEsData =3D (SEV_ES_PER_CPU_DATA *)(Ghcb + 1); >=20 > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); >=20 > // > // MOV DRn always treats MOD =3D=3D 3 no matter how encoded > // > - Register =3D GetRegisterPointer (Regs, Ext->ModRm.Rm); > + Register =3D CcGetRegisterPointer (Regs, Ext->ModRm.Rm); >=20 > // > // Using a value of 0 for ExitInfo1 means RAX holds the value > @@ -2179,24 +1646,24 @@ Dr7WriteExit ( > STATIC > UINT64 > Dr7ReadExit ( > - IN OUT GHCB *Ghcb, > - IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > - IN SEV_ES_INSTRUCTION_DATA *InstructionData > + IN OUT GHCB *Ghcb, > + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > ) > { > - SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; > - SEV_ES_PER_CPU_DATA *SevEsData; > - UINT64 *Register; > + CC_INSTRUCTION_OPCODE_EXT *Ext; > + SEV_ES_PER_CPU_DATA *SevEsData; > + UINT64 *Register; >=20 > Ext =3D &InstructionData->Ext; > SevEsData =3D (SEV_ES_PER_CPU_DATA *)(Ghcb + 1); >=20 > - DecodeModRm (Regs, InstructionData); > + CcDecodeModRm (Regs, InstructionData); >=20 > // > // MOV DRn always treats MOD =3D=3D 3 no matter how encoded > // > - Register =3D GetRegisterPointer (Regs, Ext->ModRm.Rm); > + Register =3D CcGetRegisterPointer (Regs, Ext->ModRm.Rm); >=20 > // > // If there is a cached valued for DR7, return that. Otherwise return = the > @@ -2232,12 +1699,12 @@ InternalVmgExitHandleVc ( > IN OUT EFI_SYSTEM_CONTEXT SystemContext > ) > { > - EFI_SYSTEM_CONTEXT_X64 *Regs; > - NAE_EXIT NaeExit; > - SEV_ES_INSTRUCTION_DATA InstructionData; > - UINT64 ExitCode, Status; > - EFI_STATUS VcRet; > - BOOLEAN InterruptState; > + EFI_SYSTEM_CONTEXT_X64 *Regs; > + NAE_EXIT NaeExit; > + CC_INSTRUCTION_DATA InstructionData; > + UINT64 ExitCode, Status; > + EFI_STATUS VcRet; > + BOOLEAN InterruptState; >=20 > VcRet =3D EFI_SUCCESS; >=20 > @@ -2307,11 +1774,11 @@ InternalVmgExitHandleVc ( > NaeExit =3D UnsupportedExit; > } >=20 > - InitInstructionData (&InstructionData, Ghcb, Regs); > + CcInitInstructionData (&InstructionData, Ghcb, Regs); >=20 > Status =3D NaeExit (Ghcb, Regs, &InstructionData); > if (Status =3D=3D 0) { > - Regs->Rip +=3D InstructionLength (&InstructionData); > + Regs->Rip +=3D CcInstructionLength (&InstructionData); > } else { > GHCB_EVENT_INJECTION Event; >=20 > diff --git a/OvmfPkg/Library/CcExitLib/CcInstruction.c > b/OvmfPkg/Library/CcExitLib/CcInstruction.c > new file mode 100644 > index 000000000000..0fb54b3ed553 > --- /dev/null > +++ b/OvmfPkg/Library/CcExitLib/CcInstruction.c > @@ -0,0 +1,454 @@ > +/** @file > + X64 Instruction function. > + > + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<= BR> > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include "CcInstruction.h" > + > +#define MAX_INSTRUCTION_LENGTH 15 > + > +/** > + Return a pointer to the contents of the specified register. > + > + Based upon the input register, return a pointer to the registers conte= nts > + in the x86 processor context. > + > + @param[in] Regs x64 processor context > + @param[in] Register Register to obtain pointer for > + > + @return Pointer to the contents of the requested register > + > +**/ > +UINT64 * > +CcGetRegisterPointer ( > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN 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 Reg; > +} > + > +/** > + Update the instruction parsing context for displacement bytes. > + > + @param[in, out] InstructionData Instruction parsing context > + @param[in] Size The instruction displacement size > + > +**/ > +STATIC > +VOID > +UpdateForDisplacement ( > + IN OUT CC_INSTRUCTION_DATA *InstructionData, > + IN UINTN Size > + ) > +{ > + InstructionData->DisplacementSize =3D Size; > + InstructionData->Immediate +=3D Size; > + InstructionData->End +=3D Size; > +} > + > +/** > + Determine if an instruction address if RIP relative. > + > + Examine the instruction parsing context to determine if the address of= fset > + is relative to the instruction pointer. > + > + @param[in] InstructionData Instruction parsing context > + > + @retval TRUE Instruction addressing is RIP relative > + @retval FALSE Instruction addressing is not RIP relative > + > +**/ > +STATIC > +BOOLEAN > +IsRipRelative ( > + IN CC_INSTRUCTION_DATA *InstructionData > + ) > +{ > + CC_INSTRUCTION_OPCODE_EXT *Ext; > + > + Ext =3D &InstructionData->Ext; > + > + return ((InstructionData->Mode =3D=3D LongMode64Bit) && > + (Ext->ModRm.Mod =3D=3D 0) && > + (Ext->ModRm.Rm =3D=3D 5) && > + (InstructionData->SibPresent =3D=3D FALSE)); > +} > + > +/** > + Return the effective address of a memory operand. > + > + Examine the instruction parsing context to obtain the effective memory > + address of a memory operand. > + > + @param[in] Regs x64 processor context > + @param[in] InstructionData Instruction parsing context > + > + @return The memory operand effective address > + > +**/ > +STATIC > +UINT64 > +GetEffectiveMemoryAddress ( > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN CC_INSTRUCTION_DATA *InstructionData > + ) > +{ > + CC_INSTRUCTION_OPCODE_EXT *Ext; > + UINT64 EffectiveAddress; > + > + Ext =3D &InstructionData->Ext; > + EffectiveAddress =3D 0; > + > + if (IsRipRelative (InstructionData)) { > + // > + // RIP-relative displacement is a 32-bit signed value > + // > + INT32 RipRelative; > + > + RipRelative =3D *(INT32 *)InstructionData->Displacement; > + > + UpdateForDisplacement (InstructionData, 4); > + > + // > + // Negative displacement is handled by standard UINT64 wrap-around. > + // > + return Regs->Rip + (UINT64)RipRelative; > + } > + > + switch (Ext->ModRm.Mod) { > + case 1: > + UpdateForDisplacement (InstructionData, 1); > + EffectiveAddress +=3D (UINT64)(*(INT8 *)(InstructionData->Displace= ment)); > + break; > + case 2: > + switch (InstructionData->AddrSize) { > + case Size16Bits: > + UpdateForDisplacement (InstructionData, 2); > + EffectiveAddress +=3D (UINT64)(*(INT16 *)(InstructionData- > >Displacement)); > + break; > + default: > + UpdateForDisplacement (InstructionData, 4); > + EffectiveAddress +=3D (UINT64)(*(INT32 *)(InstructionData- > >Displacement)); > + break; > + } > + > + break; > + } > + > + if (InstructionData->SibPresent) { > + INT64 Displacement; > + > + if (Ext->Sib.Index !=3D 4) { > + CopyMem ( > + &Displacement, > + CcGetRegisterPointer (Regs, Ext->Sib.Index), > + sizeof (Displacement) > + ); > + Displacement *=3D (INT64)(1 << Ext->Sib.Scale); > + > + // > + // Negative displacement is handled by standard UINT64 wrap-around= . > + // > + EffectiveAddress +=3D (UINT64)Displacement; > + } > + > + if ((Ext->Sib.Base !=3D 5) || Ext->ModRm.Mod) { > + EffectiveAddress +=3D *CcGetRegisterPointer (Regs, Ext->Sib.Base); > + } else { > + UpdateForDisplacement (InstructionData, 4); > + EffectiveAddress +=3D (UINT64)(*(INT32 *)(InstructionData- > >Displacement)); > + } > + } else { > + EffectiveAddress +=3D *CcGetRegisterPointer (Regs, Ext->ModRm.Rm); > + } > + > + return EffectiveAddress; > +} > + > +/** > + Decode a ModRM byte. > + > + Examine the instruction parsing context to decode a ModRM byte and the > SIB > + byte, if present. > + > + @param[in] Regs x64 processor context > + @param[in, out] InstructionData Instruction parsing context > + > +**/ > +VOID > +CcDecodeModRm ( > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN OUT CC_INSTRUCTION_DATA *InstructionData > + ) > +{ > + CC_INSTRUCTION_OPCODE_EXT *Ext; > + INSTRUCTION_REX_PREFIX *RexPrefix; > + INSTRUCTION_MODRM *ModRm; > + INSTRUCTION_SIB *Sib; > + > + RexPrefix =3D &InstructionData->RexPrefix; > + Ext =3D &InstructionData->Ext; > + ModRm =3D &InstructionData->ModRm; > + 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.BitR << 3) | ModRm->Bits.Reg; > + Ext->ModRm.Rm =3D (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm; > + > + Ext->RegData =3D *CcGetRegisterPointer (Regs, Ext->ModRm.Reg); > + > + if (Ext->ModRm.Mod =3D=3D 3) { > + Ext->RmData =3D *CcGetRegisterPointer (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.BitX << 3) | Sib->Bits.Index; > + Ext->Sib.Base =3D (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base; > + } > + > + Ext->RmData =3D GetEffectiveMemoryAddress (Regs, InstructionData); > + } > +} > + > +/** > + Decode instruction prefixes. > + > + Parse the instruction data to track the instruction prefixes that have > + been used. > + > + @param[in] Regs x64 processor context > + @param[in, out] InstructionData Instruction parsing context > + > + @retval EFI_SUCCESS Successfully decode Prefixes > + @retval Others Other error as indicated > +**/ > +STATIC > +EFI_STATUS > +DecodePrefixes ( > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN OUT CC_INSTRUCTION_DATA *InstructionData > + ) > +{ > + CC_INSTRUCTION_MODE Mode; > + CC_INSTRUCTION_SIZE ModeDataSize; > + CC_INSTRUCTION_SIZE ModeAddrSize; > + UINT8 *Byte; > + UINT8 ParsedLength; > + > + ParsedLength =3D 0; > + > + // > + // Always in 64-bit mode > + // > + Mode =3D LongMode64Bit; > + ModeDataSize =3D Size32Bits; > + ModeAddrSize =3D Size64Bits; > + > + InstructionData->Mode =3D Mode; > + InstructionData->DataSize =3D ModeDataSize; > + InstructionData->AddrSize =3D ModeAddrSize; > + > + InstructionData->Prefixes =3D InstructionData->Begin; > + > + Byte =3D InstructionData->Prefixes; > + for ( ; ParsedLength <=3D MAX_INSTRUCTION_LENGTH; Byte++, > InstructionData->PrefixSize++, ParsedLength++) { > + // > + // Check the 0x40 to 0x4F range using an if statement here since som= e > + // compilers don't like the "case 0x40 ... 0x4F:" syntax. This avoid= s > + // 16 case statements below. > + // > + if ((*Byte >=3D REX_PREFIX_START) && (*Byte <=3D REX_PREFIX_STOP)) { > + InstructionData->RexPrefix.Uint8 =3D *Byte; > + if ((*Byte & REX_64BIT_OPERAND_SIZE_MASK) !=3D 0) { > + InstructionData->DataSize =3D Size64Bits; > + } > + > + continue; > + } > + > + switch (*Byte) { > + case OVERRIDE_SEGMENT_CS: > + case OVERRIDE_SEGMENT_DS: > + case OVERRIDE_SEGMENT_ES: > + case OVERRIDE_SEGMENT_SS: > + if (Mode !=3D LongMode64Bit) { > + InstructionData->SegmentSpecified =3D TRUE; > + InstructionData->Segment =3D (*Byte >> 3) & 3; > + } > + > + break; > + > + case OVERRIDE_SEGMENT_FS: > + case OVERRIDE_SEGMENT_GS: > + InstructionData->SegmentSpecified =3D TRUE; > + InstructionData->Segment =3D *Byte & 7; > + break; > + > + case OVERRIDE_OPERAND_SIZE: > + if (InstructionData->RexPrefix.Uint8 =3D=3D 0) { > + InstructionData->DataSize =3D > + (Mode =3D=3D LongMode64Bit) ? Size16Bits : > + (Mode =3D=3D LongModeCompat32Bit) ? Size16Bits : > + (Mode =3D=3D LongModeCompat16Bit) ? Size32Bits : 0; > + } > + > + break; > + > + case OVERRIDE_ADDRESS_SIZE: > + InstructionData->AddrSize =3D > + (Mode =3D=3D LongMode64Bit) ? Size32Bits : > + (Mode =3D=3D LongModeCompat32Bit) ? Size16Bits : > + (Mode =3D=3D LongModeCompat16Bit) ? Size32Bits : 0; > + break; > + > + case LOCK_PREFIX: > + break; > + > + case REPZ_PREFIX: > + InstructionData->RepMode =3D RepZ; > + break; > + > + case REPNZ_PREFIX: > + InstructionData->RepMode =3D RepNZ; > + break; > + > + default: > + InstructionData->OpCodes =3D Byte; > + InstructionData->OpCodeSize =3D (*Byte =3D=3D > TWO_BYTE_OPCODE_ESCAPE) ? 2 : 1; > + > + InstructionData->End =3D Byte + InstructionData->OpCode= Size; > + InstructionData->Displacement =3D InstructionData->End; > + InstructionData->Immediate =3D InstructionData->End; > + return EFI_SUCCESS; > + } > + } > + > + return EFI_ABORTED; > +} > + > +/** > + Determine instruction length > + > + Return the total length of the parsed instruction. > + > + @param[in] InstructionData Instruction parsing context > + > + @return Length of parsed instruction > + > +**/ > +UINT64 > +CcInstructionLength ( > + IN CC_INSTRUCTION_DATA *InstructionData > + ) > +{ > + return (UINT64)(InstructionData->End - InstructionData->Begin); > +} > + > +/** > + Initialize the instruction parsing context. > + > + Initialize the instruction parsing context, which includes decoding th= e > + instruction prefixes. > + > + @param[in, out] InstructionData Instruction parsing context > + @param[in] Ghcb Pointer to the Guest-Hypervisor > Communication > + Block > + @param[in] Regs x64 processor context > + > + @retval EFI_SUCCESS Successfully initialize InstructionDa= ta > + @retval Others Other error as indicated > +**/ > +EFI_STATUS > +CcInitInstructionData ( > + IN OUT CC_INSTRUCTION_DATA *InstructionData, > + IN GHCB *Ghcb, > + IN EFI_SYSTEM_CONTEXT_X64 *Regs > + ) > +{ > + SetMem (InstructionData, sizeof (*InstructionData), 0); > + InstructionData->Ghcb =3D Ghcb; > + InstructionData->Begin =3D (UINT8 *)Regs->Rip; > + InstructionData->End =3D (UINT8 *)Regs->Rip; > + > + return DecodePrefixes (Regs, InstructionData); > +} > diff --git a/OvmfPkg/Library/CcExitLib/CcInstruction.h > b/OvmfPkg/Library/CcExitLib/CcInstruction.h > new file mode 100644 > index 000000000000..a8223a6a7d6d > --- /dev/null > +++ b/OvmfPkg/Library/CcExitLib/CcInstruction.h > @@ -0,0 +1,197 @@ > +/** @file > + Confidential Computing X64 Instruction > + > + Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<= BR> > + Copyright (c) 2022, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef CC_INSTRUCTION_H_ > +#define CC_INSTRUCTION_H_ > + > +#include > +#include > +#include > +#include > +#include > + > +// > +// Instruction execution mode definition > +// > +typedef enum { > + LongMode64Bit =3D 0, > + LongModeCompat32Bit, > + LongModeCompat16Bit, > +} CC_INSTRUCTION_MODE; > + > +// > +// Instruction size definition (for operand and address) > +// > +typedef enum { > + Size8Bits =3D 0, > + Size16Bits, > + Size32Bits, > + Size64Bits, > +} CC_INSTRUCTION_SIZE; > + > +// > +// Intruction segment definition > +// > +typedef enum { > + SegmentEs =3D 0, > + SegmentCs, > + SegmentSs, > + SegmentDs, > + SegmentFs, > + SegmentGs, > +} CC_INSTRUCTION_SEGMENT; > + > +// > +// Instruction rep function definition > +// > +typedef enum { > + RepNone =3D 0, > + RepZ, > + RepNZ, > +} CC_INSTRUCTION_REP; > + > +typedef struct { > + UINT8 Rm; > + UINT8 Reg; > + UINT8 Mod; > +} CC_INSTRUCTION_MODRM_EXT; > + > +typedef struct { > + UINT8 Base; > + UINT8 Index; > + UINT8 Scale; > +} CC_INSTRUCTION_SIB_EXT; > + > +// > +// Instruction opcode definition > +// > +typedef struct { > + CC_INSTRUCTION_MODRM_EXT ModRm; > + > + CC_INSTRUCTION_SIB_EXT Sib; > + > + UINTN RegData; > + UINTN RmData; > +} CC_INSTRUCTION_OPCODE_EXT; > + > +// > +// Instruction parsing context definition > +// > +typedef struct { > + GHCB *Ghcb; > + > + CC_INSTRUCTION_MODE Mode; > + CC_INSTRUCTION_SIZE DataSize; > + CC_INSTRUCTION_SIZE AddrSize; > + BOOLEAN SegmentSpecified; > + CC_INSTRUCTION_SEGMENT Segment; > + CC_INSTRUCTION_REP RepMode; > + > + UINT8 *Begin; > + UINT8 *End; > + > + UINT8 *Prefixes; > + UINT8 *OpCodes; > + UINT8 *Displacement; > + UINT8 *Immediate; > + > + INSTRUCTION_REX_PREFIX RexPrefix; > + > + BOOLEAN ModRmPresent; > + INSTRUCTION_MODRM ModRm; > + > + BOOLEAN SibPresent; > + INSTRUCTION_SIB Sib; > + > + UINTN PrefixSize; > + UINTN OpCodeSize; > + UINTN DisplacementSize; > + UINTN ImmediateSize; > + > + CC_INSTRUCTION_OPCODE_EXT Ext; > +} CC_INSTRUCTION_DATA; > + > +EFI_STATUS > +CcInitInstructionData ( > + IN OUT CC_INSTRUCTION_DATA *InstructionData, > + IN GHCB *Ghcb, > + IN EFI_SYSTEM_CONTEXT_X64 *Regs > + ); > + > +/** > + Return a pointer to the contents of the specified register. > + > + Based upon the input register, return a pointer to the registers conte= nts > + in the x86 processor context. > + > + @param[in] Regs x64 processor context > + @param[in] Register Register to obtain pointer for > + > + @return Pointer to the contents of the requested register > + > +**/ > +UINT64 * > +CcGetRegisterPointer ( > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN UINT8 Register > + ); > + > +/** > + Decode a ModRM byte. > + > + Examine the instruction parsing context to decode a ModRM byte and the > SIB > + byte, if present. > + > + @param[in] Regs x64 processor context > + @param[in, out] InstructionData Instruction parsing context > + > +**/ > +VOID > +CcDecodeModRm ( > + IN EFI_SYSTEM_CONTEXT_X64 *Regs, > + IN OUT CC_INSTRUCTION_DATA *InstructionData > + ); > + > +/** > + Determine instruction length > + > + Return the total length of the parsed instruction. > + > + @param[in] InstructionData Instruction parsing context > + > + @return Length of parsed instruction > + > +**/ > +UINT64 > +CcInstructionLength ( > + IN CC_INSTRUCTION_DATA *InstructionData > + ); > + > +/** > + Initialize the instruction parsing context. > + > + Initialize the instruction parsing context, which includes decoding th= e > + instruction prefixes. > + > + @param[in, out] InstructionData Instruction parsing context > + @param[in] Ghcb Pointer to the Guest-Hypervisor > Communication > + Block > + @param[in] Regs x64 processor context > + > + @retval EFI_SUCCESS Successfully initialize InstructionDa= ta > + @retval Others Other error as indicated > +**/ > +EFI_STATUS > +CcInitInstructionData ( > + IN OUT CC_INSTRUCTION_DATA *InstructionData, > + IN GHCB *Ghcb, > + IN EFI_SYSTEM_CONTEXT_X64 *Regs > + ); > + > +#endif > diff --git a/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf > b/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf > index 1ee22ce0aea1..811269dd2c06 100644 > --- a/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf > +++ b/OvmfPkg/Library/CcExitLib/SecCcExitLib.inf > @@ -24,6 +24,7 @@ > CcExitLib.c > CcExitVcHandler.c > CcExitVcHandler.h > + CcInstruction.c > SecCcExitVcHandler.c > CcExitVeHandler.c > X64/TdVmcallCpuid.nasm > -- > 2.29.2.windows.2