From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mx.groups.io with SMTP id smtpd.web11.10520.1636687290590861598 for ; Thu, 11 Nov 2021 19:21:30 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=QS5IltxF; spf=pass (domain: intel.com, ip: 192.55.52.43, mailfrom: ray.ni@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10165"; a="319269139" X-IronPort-AV: E=Sophos;i="5.87,227,1631602800"; d="scan'208";a="319269139" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Nov 2021 19:21:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,227,1631602800"; d="scan'208";a="733499511" Received: from orsmsx605.amr.corp.intel.com ([10.22.229.18]) by fmsmga006.fm.intel.com with ESMTP; 11 Nov 2021 19:21:30 -0800 Received: from orsmsx611.amr.corp.intel.com (10.22.229.24) by ORSMSX605.amr.corp.intel.com (10.22.229.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Thu, 11 Nov 2021 19:21:29 -0800 Received: from orsmsx608.amr.corp.intel.com (10.22.229.21) 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.2242.12; Thu, 11 Nov 2021 19:21:29 -0800 Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by orsmsx608.amr.corp.intel.com (10.22.229.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12 via Frontend Transport; Thu, 11 Nov 2021 19:21:29 -0800 Received: from NAM02-BN1-obe.outbound.protection.outlook.com (104.47.51.48) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2242.12; Thu, 11 Nov 2021 19:21:28 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gDt+V2/RtYzIhD9/ESpnEOSIvD0r9HFtoVAJ/w/aOoOnBXuOlh4PDCtDjWSUm7wkQ8+U5/Uyu+BGSrjUgbB8gQmDRPAouTH96EHAS61MGFZjR60AewxwD45a0BiKUHxaovH7XoBnuo+LJuyBJuH/EkJu2xBxqY6TvrKQC8DIR87LaeIH0G3ZWRhkBrOHfn7vx2TsyfIWLDo0gLEOXdvNynZkBnd26yvnBZKQ+43WyASXyOXiWRb5C/f4dGbLVtI78a5GDifQ4r/MA9Qf41Wob96oPCUi/NCI4DASyVjJ36LctG50kpq4Excbl29HpcfpXRrBM2hVLpYralVJqvC0vw== 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=JEHu5AkyM/yS018Zcb5+4ZOSXaoBDtav6x69S4kLjXA=; b=nBz9Eq+2RJc6gqGjKWGgcN6E9nOR4LgMuksBlulD7esq0MFXYQIZntYX3Gr5qlNaIYjibHWDZB0OVAY37DJcuMUUa3o9EBbOGMvPXGOFx2myr+Qk43Exu0P8cB2N08zR6W0T/MviqofAQi8ccNMsirm1WTIy9WOwbbpa3o+81vuVc6v2hHaQg8LT/99NluN1uD6ItAKPUu3USivZbf3ePECLYOvqhQrk6d4KEvNGGW2KKwb17ZxOhZDGpwtKlMdR7lvdJHy32BkRP7KDJrm6VZdlJvHQXRAnFZMeTL4Rk0xxSeAQlAW+oHgrvEZ7ulA2c5OBrRclEI30JefmKDZxjw== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=JEHu5AkyM/yS018Zcb5+4ZOSXaoBDtav6x69S4kLjXA=; b=QS5IltxFri0IK/m1nzfDaO4eTV1hTYXSQ2DyRXCOnAhc3NgpXV9YVWSPuoxLOkbRDYgyQyiaQ3IdRCCm17W6Qu5DN6icBuBhmiTRq8oeyat0GIOZzoPlMTUUwvF2QpkM32m47AZqlWR/bvlR4RzJDCRcRu0xQZzGM7VNVKhs5Hk= Received: from BN0PR11MB5696.namprd11.prod.outlook.com (2603:10b6:408:14b::11) by BN7PR11MB2578.namprd11.prod.outlook.com (2603:10b6:406:b2::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4690.16; Fri, 12 Nov 2021 03:21:27 +0000 Received: from BN0PR11MB5696.namprd11.prod.outlook.com ([fe80::317e:de35:e920:7778]) by BN0PR11MB5696.namprd11.prod.outlook.com ([fe80::317e:de35:e920:7778%3]) with mapi id 15.20.4669.013; Fri, 12 Nov 2021 03:21:27 +0000 From: "Ni, Ray" To: "Sheng, W" , "devel@edk2.groups.io" CC: "Dong, Eric" , "Kumar, Rahul1" Subject: Re: [PATCH v4] UefiCpuPkg/PiSmmCpuDxeSmm: Use SMM Interrupt Shadow Stack Thread-Topic: [PATCH v4] UefiCpuPkg/PiSmmCpuDxeSmm: Use SMM Interrupt Shadow Stack Thread-Index: AQHX12ZOeJxVJDXTS0OgChfQ8hN6Vqv/OZmQ Date: Fri, 12 Nov 2021 03:21:27 +0000 Message-ID: References: <20211112014028.9520-1-w.sheng@intel.com> In-Reply-To: <20211112014028.9520-1-w.sheng@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.6.200.16 dlp-reaction: no-action dlp-product: dlpe-windows authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: c83a1949-06d1-48b6-39c3-08d9a58b8353 x-ms-traffictypediagnostic: BN7PR11MB2578: x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:6430; x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: egOpdJhbkcnFvNsgH7qNRr/vtKfDXeWMLDE+PPQAu/39q1/2TDyJFH+d8snAK2sRbNBTv4YiIo6wRSPCQlGWVMvVZSkeNN4yq4AEUZFiGTRpck0vEJRDQmoiuXBbt1kg6tCJEWWVh16SKWrCT0SmLs8gwKnA5PAwP9XmP4tgJFZyuwrxWT7x0/5yhu5g0qvNzCMbiPHC3yLUN08Eikkw1LKS9IDoPE2cDpak/hdfRNzSUOwzT5TiGn/64JpXB2wYO4/JDa59QZXZA2MlmIkkPpLO2kZW7A1ThUrE74Si6vzy6KsuZtjkWmED5vvNEuO5oqwjjNGemUSCqGq+ylZjel4Y8RJlNU91oWqFeXuHswVKm7ie9J+YnjNyzOQ1iw0+Oe3VrB/jUpt42U/ixYUe6xHwwPOBUivMCsTl/5i3jTezmCzy04KzCcKeUCeXNR3q99YQHXeE8Q3Ri5MTJV1EYKs9CJyo0CzJCAkXnukspjMtTLMk3b0ck4t+B0eRXwEguXqbIkZDG00qooRpceRyP6ue2MWpbM0ziQn+aomfCKiwTGgJQJTvmfTMGFXCKLgik+9j6nXHA3Hs+8g+ytzFwqwZfQK+JJWYrAtLa7vefsLIcH14fIw7TiwVkcuB2tAKS+1Hnz/t0YzdR0jUpPKbX6vmWceeSdBuaEtsKsAF5wt0/tpJVzidSgRU/1g5oV3ymuACDY24ITq6MlZ7Lk03xMOqowAVxxrDd/Hse342ZzsUpO1RMzVvdx4vfiYljq4AfvGR94B5Suo0rSmPshyWRjxuuo6z7mMvVUZdAzKqCDA= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN0PR11MB5696.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(6029001)(366004)(8676002)(2906002)(33656002)(8936002)(5660300002)(6506007)(38100700002)(4326008)(38070700005)(19627235002)(30864003)(71200400001)(76116006)(52536014)(966005)(122000001)(66556008)(64756008)(66946007)(66476007)(66446008)(508600001)(186003)(55016002)(86362001)(83380400001)(107886003)(7696005)(82960400001)(9686003)(26005)(110136005)(53546011)(54906003)(316002)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?leVY/Z6+YDPXecymY3f66rKADPxHFIZDNOLwkaE0HHgcePkNTVFwOkUMT6yk?= =?us-ascii?Q?FuXXAwqRS/Z+f0WqQkZD/d56mR3r7CenLPDFaKiYR63FdMB7QEQmT31DGyq6?= =?us-ascii?Q?HQPCKACCRqU0lAqqcr0BBBEAJEgHPyie7VMUjjLD0YIaCTX0fQUTD/BzG9vz?= =?us-ascii?Q?tzoc+JXRB86FL9TcgNJbv1Y8tYBfHFHyyH7dC7PiTbaCoLdKTk54NCsNcJre?= =?us-ascii?Q?I4KN+DdlAzFTyax/H4bpawsswgpJNnGWdqQhLHskpZbEdEWYqNCATXX7IsDs?= =?us-ascii?Q?DvuKL/IrgohLYwJXU8kxLgb1yafY+Vesv7rxhB9BLU3XMK8/czyONPN5di2o?= =?us-ascii?Q?BQ3BS01NEZsr4OjXZ2BkKFpSydFsQnOt7ggc6aTN2YScGYb6iDT/qqFW86hK?= =?us-ascii?Q?O+efJWEt0tpzrER50qlq2xYzGUSNEddgHeR0qgmNSE+M+mGrMsJyiPP6e9M+?= =?us-ascii?Q?z1iugoHGWwHiTHlr+2phgLpeDKiIcbChX/pt9mxCoV7z93Sll1KeiXElVmfe?= =?us-ascii?Q?3IqBcWFq3gaYgUyMogWH44R44lQuiQUbRbnrvo1bI4l9aMLJ6t6NFR1G1XUs?= =?us-ascii?Q?LNssovZJ1AE7W2J8E1BIdjHjn4WVZvGbf2Jifl/lL/zyzvr+1Zd7Jj/whWqP?= =?us-ascii?Q?I8DvDrpeMnjLgndAclPExc6oCDAJtmJVpO8kMRPmYUceiWJGu1RSpfYPEtbW?= =?us-ascii?Q?DDMZkSuQ06dC1Ck+dG3OBI7RxZak3lREmV24IWS9mpaO9k8LHTFAUoAPtIsQ?= =?us-ascii?Q?vAe0Xlhzn40k/PqMPpfUNQhIq0G2PRfNzbtCIDpGGZrDQY8kEay9cGNzRjxK?= =?us-ascii?Q?KxHUk8qGMfXZKpwqh7X51Or0+W7IYm2QNM53ulGEnBB8+IBNsidG49RywxD+?= =?us-ascii?Q?7hqrt4ocMSBRF7nKdHhg1feEr8TfsuMsfiohkp5kkLRQbz5qV/mx/NUc5eUm?= =?us-ascii?Q?kSwNnpSheVY6GwZjWXPEZDeIS1KgTjzEeZWngc/fyhLo3iZw8A4WhBF3pQuJ?= =?us-ascii?Q?I/5zCmBrABz/i/rYJsEPLYuZ1hIvX3nB7tbPRNC1EfRjkcQshaQ2Z9OAQOkP?= =?us-ascii?Q?KngIEEraaqge/nCWQsNMM2FaRrrUnvCI9jVPrGV4BX3zNUnpY+mzbb5ISDPH?= =?us-ascii?Q?1ndnyi4fKODadVqlVavCapnXZn3fBtB/bLrOTQmzjL51/sHhtyWvzdjWeWTC?= =?us-ascii?Q?X/Jf5sWVpkMIjw1dvhXkRwsRVn3GiO7go2FjnW2J1NdxIiZy2kpEWeGAhX0i?= =?us-ascii?Q?DBep4uxKHiDJvfDtJJAE/Na4/dOLXsiSLN+wy9T5Onw9ETbUQ9Skkogg0goP?= =?us-ascii?Q?3fAYIrGvq9nukp9pQUcWPWaP4XXESt3eTeMCKl07dkQH5F6AxAUDjon74ky0?= =?us-ascii?Q?m0dcbZmk8zxtpsADN4356TlS2o6fyoeO5PyuVRnnJDORRf7pghHnFM9XkG2I?= =?us-ascii?Q?98gJu0pezLpWi3mu0SjciqIqeCr9TB6GoIrRFlMRbMBcEBUWAtZc2TyF8XtG?= =?us-ascii?Q?STQNfWPTPeJoj9uT/1beuH+qBxrqV6/88JkuBDpYdliD7jaO3V/wYOqow/y8?= =?us-ascii?Q?5At36IdQ19TYGVs1otB3pkg+8R7CBaKo/jxfg+/0NX9Mdyu71i3x5t9qTa4G?= =?us-ascii?Q?nEeo3LOqQBWlUba4zOeWDng=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN0PR11MB5696.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: c83a1949-06d1-48b6-39c3-08d9a58b8353 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Nov 2021 03:21:27.0518 (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: 2Ymo9hgyggmSiTFqHLJFQvT81qzFEMtfIUbYKPvtLZ6Dc+6sEkb83zGgHZk0NdjeZ/wQa8ASs3RqKP3niRF9xQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN7PR11MB2578 Return-Path: ray.ni@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Ray Ni I will create PR by end of my today since this patch fixes a critical issue= when enabling CET in SMM. > -----Original Message----- > From: Sheng, W > Sent: Friday, November 12, 2021 9:40 AM > To: devel@edk2.groups.io > Cc: Dong, Eric ; Ni, Ray ; Kumar, = Rahul1 > Subject: [PATCH v4] UefiCpuPkg/PiSmmCpuDxeSmm: Use SMM Interrupt Shadow S= tack >=20 > When CET shadow stack feature is enabled, it needs to use IST for the > exceptions, and uses interrupt shadow stack for the stack switch. > Shadow stack should be 32 bytes aligned. > Check IST field, when clear shadow stack token busy bit when using retf. >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3728 >=20 > Signed-off-by: Sheng Wei > Cc: Eric Dong > Cc: Ray Ni > Cc: Rahul Kumar > Reviewed-by: Ray Ni > --- > .../X64/Xcode5ExceptionHandlerAsm.nasm | 66 ++++++++++++----= -- > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 61 +++++++++++----- > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 14 ++++ > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 12 +++- > UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 81 ++++++++++++----= ------ > 5 files changed, 157 insertions(+), 77 deletions(-) >=20 > diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5Exceptio= nHandlerAsm.nasm > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerAsm= .nasm > index 4881a02848..84a12ddb88 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandle= rAsm.nasm > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandle= rAsm.nasm > @@ -15,17 +15,36 @@ > ;-----------------------------------------------------------------------= ------- > %include "Nasm.inc" >=20 > +; > +; Equivalent NASM structure of IA32_DESCRIPTOR > +; > +struc IA32_DESCRIPTOR > + .Limit CTYPE_UINT16 1 > + .Base CTYPE_UINTN 1 > +endstruc > + > +; > +; Equivalent NASM structure of IA32_IDT_GATE_DESCRIPTOR > +; > +struc IA32_IDT_GATE_DESCRIPTOR > + .OffsetLow CTYPE_UINT16 1 > + .Selector CTYPE_UINT16 1 > + .Reserved_0 CTYPE_UINT8 1 > + .GateType CTYPE_UINT8 1 > + .OffsetHigh CTYPE_UINT16 1 > + .OffsetUpper CTYPE_UINT32 1 > + .Reserved_1 CTYPE_UINT32 1 > +endstruc > + > ; > ; CommonExceptionHandler() > ; >=20 > %define VC_EXCEPTION 29 > -%define PF_EXCEPTION 14 >=20 > extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions > extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag > extern ASM_PFX(CommonExceptionHandler) > -extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) >=20 > SECTION .data >=20 > @@ -282,42 +301,49 @@ DrFinish: >=20 > ; The follow algorithm is used for clear shadow stack token busy bit= . > ; The comment is based on the sample shadow stack. > + ; Shadow stack is 32 bytes aligned. > ; The sample shadow stack layout : > ; Address | Context > ; +-------------------------+ > - ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L),= after SAVEPREVSSP. > + ; 0xFB8 | FREE | It is 0xFC0|0x02|(LMA & CS.L),= after SAVEPREVSSP. > ; +-------------------------+ > - ; 0xFD8 | Prev SSP | > + ; 0xFC0 | Prev SSP | > ; +-------------------------+ > - ; 0xFE0 | RIP | > + ; 0xFC8 | RIP | > ; +-------------------------+ > - ; 0xFE8 | CS | > + ; 0xFD0 | CS | > ; +-------------------------+ > - ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSB= SY > + ; 0xFD8 | 0xFD8 | BUSY | BUSY flag cleared after CLRSSB= SY > ; +-------------------------+ > - ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) | > + ; 0xFE0 | 0xFC0|0x02|(LMA & CS.L) | > ; +-------------------------+ > ; Instructions for Intel Control Flow Enforcement Technology (CET) a= re supported since NASM version 2.15.01. > cmp qword [ASM_PFX(mDoFarReturnFlag)], 0 > jz CetDone > - cmp qword [rbp + 8], PF_EXCEPTION ; check if it is a Page Faul= t > - jnz CetDone > - cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0 > - jz CetDone > mov rax, cr4 > - and rax, 0x800000 ; check if CET is enabled > + and rax, 0x800000 ; Check if CET is enabled > + jz CetDone > + sub rsp, 0x10 > + sidt [rsp] > + mov rcx, qword [rsp + IA32_DESCRIPTOR.Base]; Get IDT base addres= s > + add rsp, 0x10 > + mov rax, qword [rbp + 8]; Get exception number > + sal rax, 0x04 ; Get IDT offset > + add rax, rcx ; Get IDT gate descriptor address > + mov al, byte [rax + IA32_IDT_GATE_DESCRIPTOR.Reserved_0] > + and rax, 0x01 ; Check IST field > jz CetDone > - ; SSP should be 0xFD8 at this point > + ; SSP should be 0xFC0 at this point > mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor= shadow stack token > - INCSSP_RAX ; After this SSP should be 0xFF8 > - SAVEPREVSSP ; now the shadow stack restore token wil= l be created at 0xFD0 > - READSSP_RAX ; Read new SSP, SSP should be 0x1000 > + INCSSP_RAX ; After this SSP should be 0xFE0 > + SAVEPREVSSP ; now the shadow stack restore token wil= l be created at 0xFB8 > + READSSP_RAX ; Read new SSP, SSP should be 0xFE8 > sub rax, 0x10 > - CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 = after this > + CLRSSBSY_RAX ; Clear token at 0xFD8, SSP should be 0 = after this > sub rax, 0x20 > - RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP wil= l be 0xFD0 > + RSTORSSP_RAX ; Restore to token at 0xFB8, new SSP wil= l be 0xFB8 > mov rax, 0x01 ; Pop off the new save token created > - INCSSP_RAX ; SSP should be 0xFD8 now > + INCSSP_RAX ; SSP should be 0xFC0 now > CetDone: >=20 > cli > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSm= mCpuDxeSmm/PiSmmCpuDxeSmm.c > index 67ad9a4c07..2b2e1a5390 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c > @@ -861,35 +861,58 @@ PiCpuSmmEntry ( > mSmmStackSize =3D EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdC= puSmmStackSize))); > if (FeaturePcdGet (PcdCpuSmmStackGuard)) { > // > - // 2 more pages is allocated for each processor. > - // one is guard page and the other is known good stack. > + // SMM Stack Guard Enabled > + // 2 more pages is allocated for each processor, one is guard page= and the other is known good stack. > // > - // +-------------------------------------------+-----+--------------= -----------------------------+ > - // | Known Good Stack | Guard Page | SMM Stack | ... | Known Good St= ack | Guard Page | SMM Stack | > - // +-------------------------------------------+-----+--------------= -----------------------------+ > - // | | | = | > - // |<-------------- Processor 0 -------------->| |<-------------= - Processor n -------------->| > + // +--------------------------------------------------+-----+-------= -------------------------------------------+ > + // | Known Good Stack | Guard Page | SMM Stack | ... | Known = Good Stack | Guard Page | SMM Stack | > + // +--------------------------------------------------+-----+-------= -------------------------------------------+ > + // | 4K | 4K PcdCpuSmmStackSize| | = 4K | 4K PcdCpuSmmStackSize| > + // |<---------------- mSmmStackSize ----------------->| |<------= ---------- mSmmStackSize ----------------->| > + // | | | = | > + // |<------------------ Processor 0 ----------------->| |<------= ------------ Processor n ----------------->| > // > mSmmStackSize +=3D EFI_PAGES_TO_SIZE (2); > } >=20 > mSmmShadowStackSize =3D 0; > if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) !=3D 0) && mCetS= upported) { > - // > - // Append Shadow Stack after normal stack > - // > - // |=3D Stacks > - // +--------------------------------------------------+-------------= --------------------------------------------------+ > - // | Known Good Stack | Guard Page | SMM Stack | Known Good S= hadow Stack | Guard Page | SMM Shadow Stack | > - // +--------------------------------------------------+-------------= --------------------------------------------------+ > - // | |PcdCpuSmmStackSize| = |PcdCpuSmmShadowStackSize| > - // |<---------------- mSmmStackSize ----------------->|<------------= --------- mSmmShadowStackSize ------------------->| > - // | = | > - // |<-------------------------------------------- Processor N ------= ------------------------------------------------->| > - // > mSmmShadowStackSize =3D EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet= 32 (PcdCpuSmmShadowStackSize))); > + > if (FeaturePcdGet (PcdCpuSmmStackGuard)) { > + // > + // SMM Stack Guard Enabled > + // Append Shadow Stack after normal stack > + // 2 more pages is allocated for each processor, one is guard pa= ge and the other is known good shadow stack. > + // > + // |=3D Stacks > + // +--------------------------------------------------+-----------= ----------------------------------------------------+ > + // | Known Good Stack | Guard Page | SMM Stack | Known Good= Shadow Stack | Guard Page | SMM Shadow Stack | > + // +--------------------------------------------------+-----------= ----------------------------------------------------+ > + // | 4K | 4K |PcdCpuSmmStackSize| = 4K | 4K |PcdCpuSmmShadowStackSize| > + // |<---------------- mSmmStackSize ----------------->|<----------= ----------- mSmmShadowStackSize ------------------->| > + // | = | > + // |<-------------------------------------------- Processor N ----= --------------------------------------------------->| > + // > mSmmShadowStackSize +=3D EFI_PAGES_TO_SIZE (2); > + } else { > + // > + // SMM Stack Guard Disabled (Known Good Stack is still required fo= r potential stack switch.) > + // Append Shadow Stack after normal stack with 1 more page as kn= own good shadow stack. > + // 1 more pages is allocated for each processor, it is known goo= d stack. > + // > + // > + // |=3D Stacks > + // +-------------------------------------+------------------------= --------------------------+ > + // | Known Good Stack | SMM Stack | Known Good Shadow Stack= | SMM Shadow Stack | > + // +-------------------------------------+------------------------= --------------------------+ > + // | 4K |PcdCpuSmmStackSize| 4K = |PcdCpuSmmShadowStackSize| > + // |<---------- mSmmStackSize ---------->|<--------------- mSmmSha= dowStackSize ------------>| > + // | = | > + // |<-------------------------------- Processor N ----------------= ------------------------->| > + // > + mSmmShadowStackSize +=3D EFI_PAGES_TO_SIZE (1); > + mSmmStackSize +=3D EFI_PAGES_TO_SIZE (1); > } > } >=20 > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSm= mCpuDxeSmm/PiSmmCpuDxeSmm.h > index 2248a8c5ee..fc9b748948 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > @@ -557,6 +557,20 @@ InitializeIDTSmmStackGuard ( > VOID > ); >=20 > +/** > + Initialize IDT IST Field. > + > + @param[in] ExceptionType Exception type. > + @param[in] Ist IST value. > + > +**/ > +VOID > +EFIAPI > +InitializeIdtIst ( > + IN EFI_EXCEPTION_TYPE ExceptionType, > + IN UINT8 Ist > + ); > + > /** > Initialize Gdt for all processors. >=20 > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCp= uDxeSmm/X64/PageTbl.c > index d6f8dd94d3..211a78b1c4 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > @@ -481,7 +481,17 @@ SmmInitPageTable ( > // Additional SMM IDT initialization for SMM stack guard > // > if (FeaturePcdGet (PcdCpuSmmStackGuard)) { > - InitializeIDTSmmStackGuard (); > + DEBUG ((DEBUG_INFO, "Initialize IDT IST field for SMM Stack Guard\n"= )); > + InitializeIdtIst (EXCEPT_IA32_PAGE_FAULT, 1); > + } > + > + // > + // Additional SMM IDT initialization for SMM CET shadow stack > + // > + if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) !=3D 0) && mCetS= upported) { > + DEBUG ((DEBUG_INFO, "Initialize IDT IST field for SMM Shadow Stack\n= ")); > + InitializeIdtIst (EXCEPT_IA32_PAGE_FAULT, 1); > + InitializeIdtIst (EXCEPT_IA32_MACHINE_CHECK, 1); > } >=20 > // > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/Pi= SmmCpuDxeSmm/X64/SmmFuncsArch.c > index ca3f5ff91a..ce7afce6d4 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c > @@ -24,24 +24,24 @@ UINT32 mCetInterruptSspTable; > UINTN mSmmInterruptSspTables; >=20 > /** > - Initialize IDT for SMM Stack Guard. > + Initialize IDT IST Field. > + > + @param[in] ExceptionType Exception type. > + @param[in] Ist IST value. >=20 > **/ > VOID > EFIAPI > -InitializeIDTSmmStackGuard ( > - VOID > +InitializeIdtIst ( > + IN EFI_EXCEPTION_TYPE ExceptionType, > + IN UINT8 Ist > ) > { > IA32_IDT_GATE_DESCRIPTOR *IdtGate; >=20 > - // > - // If SMM Stack Guard feature is enabled, set the IST field of > - // the interrupt gate for Page Fault Exception to be 1 > - // > IdtGate =3D (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base; > - IdtGate +=3D EXCEPT_IA32_PAGE_FAULT; > - IdtGate->Bits.Reserved_0 =3D 1; > + IdtGate +=3D ExceptionType; > + IdtGate->Bits.Reserved_0 =3D Ist; > } >=20 > /** > @@ -89,7 +89,7 @@ InitGdt ( > GdtDescriptor->Bits.BaseMid =3D (UINT8)((UINTN)TssBase >> 16); > GdtDescriptor->Bits.BaseHigh =3D (UINT8)((UINTN)TssBase >> 24); >=20 > - if (FeaturePcdGet (PcdCpuSmmStackGuard)) { > + if ((FeaturePcdGet (PcdCpuSmmStackGuard)) || ((PcdGet32 (PcdControlF= lowEnforcementPropertyMask) !=3D 0) && > mCetSupported)) { > // > // Setup top of known good stack as IST1 for each processor. > // > @@ -177,8 +177,16 @@ InitShadowStack ( >=20 > if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) !=3D 0) && mCetS= upported) { > SmmShadowStackSize =3D EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet3= 2 (PcdCpuSmmShadowStackSize))); > + // > + // Add 1 page as known good shadow stack > + // > + SmmShadowStackSize +=3D EFI_PAGES_TO_SIZE (1); > + > if (FeaturePcdGet (PcdCpuSmmStackGuard)) { > - SmmShadowStackSize +=3D EFI_PAGES_TO_SIZE (2); > + // > + // Add one guard page between Known Good Shadow Stack and SMM Shad= ow Stack. > + // > + SmmShadowStackSize +=3D EFI_PAGES_TO_SIZE (1); > } > mCetPl0Ssp =3D (UINT32)((UINTN)ShadowStack + SmmShadowStackSize - si= zeof(UINT64)); > PatchInstructionX86 (mPatchCetPl0Ssp, mCetPl0Ssp, 4); > @@ -186,33 +194,32 @@ InitShadowStack ( > DEBUG ((DEBUG_INFO, "ShadowStack - 0x%x\n", ShadowStack)); > DEBUG ((DEBUG_INFO, " SmmShadowStackSize - 0x%x\n", SmmShadowStackS= ize)); >=20 > - if (FeaturePcdGet (PcdCpuSmmStackGuard)) { > - if (mSmmInterruptSspTables =3D=3D 0) { > - mSmmInterruptSspTables =3D (UINTN)AllocateZeroPool(sizeof(UINT64= ) * 8 * gSmmCpuPrivate- > >SmmCoreEntryContext.NumberOfCpus); > - ASSERT (mSmmInterruptSspTables !=3D 0); > - DEBUG ((DEBUG_INFO, "mSmmInterruptSspTables - 0x%x\n", mSmmInter= ruptSspTables)); > - } > - > - // > - // The highest address on the stack (0xFF8) is a save-previous-ssp= token pointing to a location that is 40 bytes away - 0xFD0. > - // The supervisor shadow stack token is just above it at address 0= xFF0. This is where the interrupt SSP table points. > - // So when an interrupt of exception occurs, we can use SAVESSP/RE= STORESSP/CLEARSSBUSY for the supervisor shadow > stack, > - // due to the reason the RETF in SMM exception handler cannot clea= r the BUSY flag with same CPL. > - // (only IRET or RETF with different CPL can clear BUSY flag) > - // Please refer to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64 f= or the full stack frame at runtime. > - // > - InterruptSsp =3D (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1= ) - sizeof(UINT64)); > - *(UINT64 *)(UINTN)InterruptSsp =3D (InterruptSsp - sizeof(UINT64) = * 4) | 0x2; > - mCetInterruptSsp =3D InterruptSsp - sizeof(UINT64); > - > - mCetInterruptSspTable =3D (UINT32)(UINTN)(mSmmInterruptSspTables += sizeof(UINT64) * 8 * CpuIndex); > - InterruptSspTable =3D (UINT64 *)(UINTN)mCetInterruptSspTable; > - InterruptSspTable[1] =3D mCetInterruptSsp; > - PatchInstructionX86 (mPatchCetInterruptSsp, mCetInterruptSsp, 4); > - PatchInstructionX86 (mPatchCetInterruptSspTable, mCetInterruptSspT= able, 4); > - DEBUG ((DEBUG_INFO, "mCetInterruptSsp - 0x%x\n", mCetInterruptSsp)= ); > - DEBUG ((DEBUG_INFO, "mCetInterruptSspTable - 0x%x\n", mCetInterrup= tSspTable)); > + if (mSmmInterruptSspTables =3D=3D 0) { > + mSmmInterruptSspTables =3D (UINTN)AllocateZeroPool(sizeof(UINT64) = * 8 * gSmmCpuPrivate- > >SmmCoreEntryContext.NumberOfCpus); > + ASSERT (mSmmInterruptSspTables !=3D 0); > + DEBUG ((DEBUG_INFO, "mSmmInterruptSspTables - 0x%x\n", mSmmInterru= ptSspTables)); > } > + > + // > + // The highest address on the stack (0xFE0) is a save-previous-ssp t= oken pointing to a location that is 40 bytes away - 0xFB8. > + // The supervisor shadow stack token is just above it at address 0xF= D8. This is where the interrupt SSP table points. > + // So when an interrupt of exception occurs, we can use SAVESSP/REST= ORESSP/CLEARSSBUSY for the supervisor shadow > stack, > + // due to the reason the RETF in SMM exception handler cannot clear = the BUSY flag with same CPL. > + // (only IRET or RETF with different CPL can clear BUSY flag) > + // Please refer to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64 for= the full stack frame at runtime. > + // According to SDM (ver. 075 June 2021), shadow stack should be 32 = bytes aligned. > + // > + InterruptSsp =3D (UINT32)(((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1)= - (sizeof(UINT64) * 4)) & ~0x1f); > + *(UINT64 *)(UINTN)InterruptSsp =3D (InterruptSsp - sizeof(UINT64) * = 4) | 0x2; > + mCetInterruptSsp =3D InterruptSsp - sizeof(UINT64); > + > + mCetInterruptSspTable =3D (UINT32)(UINTN)(mSmmInterruptSspTables + s= izeof(UINT64) * 8 * CpuIndex); > + InterruptSspTable =3D (UINT64 *)(UINTN)mCetInterruptSspTable; > + InterruptSspTable[1] =3D mCetInterruptSsp; > + PatchInstructionX86 (mPatchCetInterruptSsp, mCetInterruptSsp, 4); > + PatchInstructionX86 (mPatchCetInterruptSspTable, mCetInterruptSspTab= le, 4); > + DEBUG ((DEBUG_INFO, "mCetInterruptSsp - 0x%x\n", mCetInterruptSsp)); > + DEBUG ((DEBUG_INFO, "mCetInterruptSspTable - 0x%x\n", mCetInterruptS= spTable)); > } > } >=20 > -- > 2.16.2.windows.1