From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web11.45447.1673491429047554929 for ; Wed, 11 Jan 2023 18:43:49 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=S52VHHG3; spf=pass (domain: intel.com, ip: 192.55.52.136, 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=1673491429; x=1705027429; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=GbyeI+YkOZUiZK2/qOCigGYiLHb9qYQnFmonruOa6GY=; b=S52VHHG3XILyn/7gzJTM3pRyTQ3Qwg3T8xxCIlUElkANQ11zF8X/pgEI qLC5/RXcoaVnNJcq3PU2wqK885GfUC+/fCH5yxIH/eFbUH87kDiju5beC t7dOLjwQkYPFHfx3SF5NyvsaDeHxpnoPww4kVMlkm6RJzhmjxDiKX4u1m TZmuHAfmEgkYZeAqoX6FqO27AyrZaEzHn7bsFADLkSyZ1NHw+T8gIhFEJ lurnwJG22pvucoO0BheviIp3r/kqhj1clNMZ1Lcb2z4s7Ya9BUrTTU4g+ o5LESEabGGDwhnm7em75D9PxrE+3GwJE3YbhA1NaWCUDD9gQKXyXGcoU1 A==; X-IronPort-AV: E=McAfee;i="6500,9779,10586"; a="303293375" X-IronPort-AV: E=Sophos;i="5.96,318,1665471600"; d="scan'208";a="303293375" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2023 18:43:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10586"; a="781612128" X-IronPort-AV: E=Sophos;i="5.96,318,1665471600"; d="scan'208";a="781612128" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by orsmga004.jf.intel.com with ESMTP; 11 Jan 2023 18:43:47 -0800 Received: from orsmsx611.amr.corp.intel.com (10.22.229.24) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Wed, 11 Jan 2023 18:43:47 -0800 Received: from orsmsx603.amr.corp.intel.com (10.22.229.16) by ORSMSX611.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Wed, 11 Jan 2023 18:43:47 -0800 Received: from ORSEDG601.ED.cps.intel.com (10.7.248.6) by orsmsx603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16 via Frontend Transport; Wed, 11 Jan 2023 18:43:47 -0800 Received: from NAM04-DM6-obe.outbound.protection.outlook.com (104.47.73.42) by edgegateway.intel.com (134.134.137.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.16; Wed, 11 Jan 2023 18:43:46 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UOHCBGTh7EZjAUrLxRjpO/bdwhCx23uQ3IryOcOvJtgpO/vCG1FAvRdRvDwf+HB/GexJ9tgCbaBjhSogjjUDT13yRgWLlQeZPBM6+8TMM2PUoa1trQJHgaIZ993K7Yf9o7y5sUfVyfZlAK3Pi+VdHzHQjn5JSh0PH8AIQ07RHO0WCFn60j3ihOgamK4TXXAtrpw9jKX0EtX0nGTh5YGMSNRm+Xjb+0+N+HYGxC35XXLitdxnDQ4HqZG82kgJEnfQfUKgHUplENPM2GZdWWpnGW88BvKo7IzJs9EZKsNu+jxZ1Zo0UqTWbG79Iom/w1m+ZnxolGyWGRAtUFFlA9GOMQ== 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=qWxgH49dAfG2DpnTeKt7uP5vokX4BmbjZMaLSyZ0Opg=; b=jvoRnp5xBF0eDOWFNddm+6eWg71D0TNdfdCX+8lopjUuXcwWWzZNmzq5gdz9XpKuNKOmuOdQGUuMTk4bBYBEIatRP6MvviIZDNzp6ghU79b+OjuIFhVKQFe3Q3ZyMcHafeFLu/dBmzEtduxKdfs7RwoKmJngQIPSEyl50G0adulT+3e7fhVjOnD/NWhdpxrOaDkD2ksbvRR46MleAtTuzcZSEFTX34ZTJ4dboQRJ7W0EmZ2tDKin/Fp91oxnT31g4q9589zb5xhIdch2krRUSDJ14BUzHdXUPmvPjSPOBgx2s1vfBROptv17aKbdBEtrnpnPjvX4rn1E9UtQzD7kkw== 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 PH7PR11MB6032.namprd11.prod.outlook.com (2603:10b6:510:1d3::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.18; Thu, 12 Jan 2023 02:43:43 +0000 Received: from MW4PR11MB5872.namprd11.prod.outlook.com ([fe80::5f56:1bdc:2eae:c041]) by MW4PR11MB5872.namprd11.prod.outlook.com ([fe80::5f56:1bdc:2eae:c041%7]) with mapi id 15.20.6002.013; Thu, 12 Jan 2023 02:43:43 +0000 From: "Yao, Jiewen" To: "Xu, Min M" , "devel@edk2.groups.io" CC: "Aktas, Erdem" , James Bottomley , Gerd Hoffmann , Tom Lendacky , "Afranji, Ryan" Subject: Re: [PATCH V2 2/2] OvmfPkg/CcExitLib: Refactor TDX MmioExit Thread-Topic: [PATCH V2 2/2] OvmfPkg/CcExitLib: Refactor TDX MmioExit Thread-Index: AQHZJIYEEX5TXl6wzkWIP8i/w4LIq66aFYfA Date: Thu, 12 Jan 2023 02:43:43 +0000 Message-ID: References: <20230109235612.439-1-min.m.xu@intel.com> <20230109235612.439-3-min.m.xu@intel.com> In-Reply-To: <20230109235612.439-3-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_|PH7PR11MB6032:EE_ x-ms-office365-filtering-correlation-id: 8dd49880-8f65-4e7c-42e1-08daf446d22f 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: D+wN7s+53zC5+yRS+0mbAqMWdFdcRp9/QNBz9eQ2gk2sdXxixHUBwTE0p+wsdtbWTH2OolyS2iTUmBIWFfYxmzM9z8yDUfT0rd+JsPAm3kakQXD/Sy8/zyOTpw2rBZPZIpDSjC2Eh3WHjz/7v6havQ1o6SrL/xjnrSLNp8X4+6TpIniFEgJ+u4jjAcxHmaWD9ezGSZg3CeDwKd/rROg81NOj2ITEvEnHUWSRACi12STGukBUv1nG7OkV7UKfz8E92nJKIz6x038ILKWBAAZqNOzaMNiafxpnNvPG6r1xbf4iK0iQZEMNH/I7S4U9AVu42G16UU+gmdQ/e6Kxvzc28UoZ3xNUzV6ZARtv5DXNSMtwC9hGq11YCLDCTCjSURECmwfXhvvPuv5XJRPTloaT5maDt7F34f23wtra11mc4GD3TANEjK33tPCHne4rKtlHkw1WBlw2wGiyefgOclVmrQPt1BV09Yml6FAG9S8a4ZEiZrbQunN/fokqebhT3fvBMNjQfZFfC3G0a8lD4MXNguqCNY67QD3nen3efpTbI7sGfLPcs6AnfNDc7K7DGLMyvmFEvst3uv0ZBDvWkHpCjXxtR2ie73j1hH2GeHSYxCbDo137jwPOqoiZnQ1ZTRgyT8YOp+2xJZmJitXCeVC94edYNyGxdR+Cp1JFDeKLrzf0uqqx0ye3a3IPus/1nWWOgbi57YJyNFmsnI7hhEglVYHCGwHwEcC7bgdzZYIw5z0= 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)(396003)(346002)(39860400002)(136003)(366004)(376002)(451199015)(6506007)(38100700002)(122000001)(82960400001)(53546011)(2906002)(478600001)(966005)(33656002)(30864003)(316002)(26005)(186003)(5660300002)(7696005)(71200400001)(9686003)(86362001)(8936002)(83380400001)(38070700005)(52536014)(55016003)(41300700001)(64756008)(110136005)(8676002)(76116006)(66946007)(66556008)(66476007)(66446008)(54906003)(4326008)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?MD9foSphvuEq4GUTqvlW725Iq+UdETu50Boo8Y2rCGHhHb9xoD1Pt3W+/WoR?= =?us-ascii?Q?z6dqFm+kFjh4Zyk5ROQJXsNpwH29vg6eqpgzk4f+49MtcQgeEVAN8Hw9H/UX?= =?us-ascii?Q?H7b4ntwKmC7z0XGDhK7PF6AKH5yICo3aPUWYcsydjgRLYF+TNnoeOqnu870/?= =?us-ascii?Q?lCQ9yzvb0F5de3ZDBFZLabNe6skDw/JvfSPwTvOZ6pZsB19InRCJGWX3CDRi?= =?us-ascii?Q?oF3tMDdCBcO1VQerPMidZZQhITz8ryqbh3WVYjalEJ9nHKCvSQ2BWhvgXOak?= =?us-ascii?Q?mho6C0evFcJSQODwUeBEWvDjtBNHj5gB4sDJ4FSrAdWtMioa3ERC+JtbIuaJ?= =?us-ascii?Q?4ot+FQPIKsHNf3agSFPTpvHhIr1EmmxT74fkLawqoxQYh2t1NRf1P9DGD9zv?= =?us-ascii?Q?9lan3SeS9zxBNCdtRxrsQwuvDz38KQfgTGgYiadQIXlCDIsNXdYWSV/7YAp0?= =?us-ascii?Q?YKT5xvscg1aW1ZejUHSnoZnmRXTHJcBQnB8jxpwp7jcZpavApUymLhykMRoY?= =?us-ascii?Q?BHOo6ITtKIEqgsrZl5vbMimakVjaic3pX6wQX/gsHBkcz573x8Jwh2gGGbs8?= =?us-ascii?Q?0+OcyaPIE6fqv/8gfLsspeyevXJ7Ro7zFsjcpDfWCpBMRE1o9zJxtnD8Mas5?= =?us-ascii?Q?T1H0IhETuOiyCVt5yd3x3OClDFeHLCF68C6bxdy/82YjjQAbaXHjVJU+Qo6H?= =?us-ascii?Q?C8TO5c3c3hAFHEPWCfsk8qV9meeaqjGCw4RAUctJiY/tpFyQoX5dxH+ZRxQJ?= =?us-ascii?Q?pePR/7QrT3qpCrIjtF4CgwRTE/FOUGMgmckq4ApkjxUwx3LC4G4urL+lXIOx?= =?us-ascii?Q?uDSnKclWcSGRDQzoLQRllrl5S2071E3gpXPmlhYQoX8bRxncD7U+f+JVXsZJ?= =?us-ascii?Q?TyMFnsarfy7ocLs7MjRA1UfpLwCeiYjEH4hDsMLFzHVIp306iGl4p7LgbVBQ?= =?us-ascii?Q?DoaXcdcshw//kpziQSVWczwqRs/oaSHIDeuovrrPTMdzRDh87kT+aX5QyGOs?= =?us-ascii?Q?TryNreJ6t1aQrUM6cVCbw2Ug7or7DBwfqJWzUQKJRsRu8BXPouT3haiFMyTM?= =?us-ascii?Q?ebfxltmbA/3Ygo8cK+++YOrYYU4yiwY7dpyAqiw16Yvb64jyaQreBK0GF7YL?= =?us-ascii?Q?qNxmB85WowaZvmHoElrbtOq3RFC6486bVRnm1Y4+ucZwtMVro4KduYVcjhhQ?= =?us-ascii?Q?+ZviygmTISvAXQf2vuUui27G5H81y+rzZAfDjjbn3RmI5Dte+yI/MU1a0811?= =?us-ascii?Q?tcQ8g9Lg4NlnYTp1AQQ9/7hUKbHqKSAg+S27OPb+P3IOcyn2gZIQK8TpSoDY?= =?us-ascii?Q?3vckZTtguA1dcSyAdNGeXAr0bE7UEeK1qxJkwq5HaiB/odIkBybcO2D6LRbc?= =?us-ascii?Q?NrE7iAsY+hkOptHirtlzNe4qpSUo+HE9CzwEBBvEoe0ZMQBDscRV5efj/Atx?= =?us-ascii?Q?ttzs21D87rbls0E/U0F+ej3dmBbIZH8zqgo/THBr7hJEvSgOJNJppQFneO9/?= =?us-ascii?Q?REXVCq7Q3kF/7hDw6wyo3rkiSkFatRSh+vT2CYyebBTnr3zxoeKIs4dpUJW5?= =?us-ascii?Q?/N4chwmx4dgVoIBteeD7h24phLNKZgeDBpEtusMY?= 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: 8dd49880-8f65-4e7c-42e1-08daf446d22f X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Jan 2023 02:43:43.7391 (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: Jh/gp6Jl3k39nk2STwBlHJ9ugjo7MoqUem5NxjuJtqv55lcntR3wNDl+0ZnnwYgSB62DaMfu8Bxn9BsdjIOB4A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR11MB6032 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 Hi Below code is suspicious. =3D=3D=3D=3D=3D=3D=3D=3D if (!EFI_ERROR (Status)) { // // We change instruction length to reflect true size so handler can // bump rip // Veinfo->ExitInstructionLength =3D (UINT32)(CcInstructionLength (&Instr= uctionData)); TdxDecodeInstruction ((UINT8 *)Regs->Rip, Veinfo->ExitInstructionLength= ); } return 0; =3D=3D=3D=3D=3D=3D=3D=3D It should not return 0 if Status is not SUCCESS Thank you Yao, Jiewen > -----Original Message----- > From: Xu, Min M > Sent: Tuesday, January 10, 2023 7:56 AM > To: devel@edk2.groups.io > Cc: Xu, Min M ; Aktas, Erdem > ; James Bottomley ; Yao, > Jiewen ; Gerd Hoffmann ; > Tom Lendacky ; Afranji, Ryan > > Subject: [PATCH V2 2/2] OvmfPkg/CcExitLib: Refactor TDX MmioExit >=20 > From: Min M Xu >=20 > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4169 >=20 > The previous TDX MmioExit doesn't handle the Mmio instructions correctly > in some scenarios. This patch refactors the implementation to fix the > issues. >=20 > 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(-) >=20 > 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) && > (MmioSize !=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, > GuestPA, *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 > includes 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- > >AddrSize); > + InstructionData->End +=3D InstructionData->ImmediateSize; > + CopyMem (&Address, InstructionData->Immediate, InstructionData- > >ImmediateSize); > + > + 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- > >ImmediateSize); > + > + 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.ModR= m.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- > >AddrSize); > + 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.ModR= m.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.ModR= m.Reg); > + SetMem (Register, (UINTN)(1 << InstructionData->DataSize), SignByt= e); > + > + 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", > __FUNCTION__, TdStatus)); > + goto FatalError; > } >=20 > if ((Veinfo->GuestPA & TdSharedPageMask) =3D=3D 0) { > - DEBUG ((DEBUG_ERROR, "EPT-violation #VE on private memory is not > allowed!")); > - TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0); > - CpuDeadLoop (); > + DEBUG ((DEBUG_ERROR, "%a: EPT-violation #VE on private memory is not > allowed!", __FUNCTION__)); > + goto FatalError; > } >=20 > - // > - // Default to 32bit transfer > - // > - OpSize =3D 4; > + Status =3D ParseMmioExitInstructions (Regs, &InstructionData, > &ParsedInstruction); > + 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, > Veinfo->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.Bits.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, > Val, 0); > - break; > - case 0xC7: > - CopyMem ((void *)&Val, Rip, OpSize); > - Status =3D TdVmCall (TDVMCALL_MMIO, MmioSize, 1, Veinfo->GuestPA, > Val, 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 > (&InstructionData)); > + TdxDecodeInstruction ((UINT8 *)Regs->Rip, Veinfo- > >ExitInstructionLength); > } >=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.ExitInstructionLength; > -- > 2.29.2.windows.2