From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM02-DM3-obe.outbound.protection.outlook.com (NAM02-DM3-obe.outbound.protection.outlook.com [40.107.95.73]) by mx.groups.io with SMTP id smtpd.web08.34.1622070718821521219 for ; Wed, 26 May 2021 16:11:59 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=Z1QFbP3k; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.95.73, mailfrom: brijesh.singh@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=leXblx0aVC9HqZIL1jT9Bslub5usY5TB5/nwbwnAFEArJ4R5rxS51zGcW7PgfwQl+cpdWKBsrSBRfAUvLa+VAf/0aEx3QCVeTDtAkvbOSAfH8WEcEha1/bNYv1VNnCBDUjAWvUry16mg8ZuFRkCe9rwIGqZwrAPcltDTxvqlD164d71wUdO1iTgpv0/FC1LDvf6nEaTMf9TMCmYrFtuHvM81YbNrbquSfkO5ip4ms8/C0RzQyJfnXLueY+VYmM9Mk8a9G+mTYTk0OicPUJYpNSbmoMmjGYbztfLcFTCfPiHUaB0O29mQeB2XMQdezQ8tDiED3o2vLsZRsZ1+Z5l/KA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BkBBod/N+0UUX05SAZqFFEc0aPxtbhbGqaApRQAw5Vs=; b=BBwgoIzGzLb9YUOXVS2pCHS9+1Pgz1ZtQswrYvCKQyH5/5eJusGgGguV0vk196ECNk60vXHYS6UoB6blM+38I46l+txcnf/nXh0mMUQxPhhHrUIflH+ahejEAeBaWbolDgRXXBDeRMgTEDCLdOxinJIiJG1k1kYSnsiJGkhz9Bu57aV5PMVQAJ9bB2nDeKy+6gG4Yj9JUeQX82P6zIxngi3DSoFuPRm0utRDry/vPBV2nlV/OJ/EFZlsTzK+9TZVajX+8C31wRGqk7Hnf2ZiJjJt9l2YQ+A3tW3VhGPWzyWyhYeGNYO6CgfAHtd4kf2B3JeWfvoqn31u4r7QIBGQtA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BkBBod/N+0UUX05SAZqFFEc0aPxtbhbGqaApRQAw5Vs=; b=Z1QFbP3kR0fmathxu0z/Ew1+E5Eh7YRFuOHlq9C/cPBWUb2GwZaPwHB7yFr7noAEU+txauWlzZmAuEpNygj8kHX/1yhoiO+CtaTBAB+MqXkZ1BcIz49qiTpDZbPgZBymjwi82b/jDrHj1QiAuA+hVo7W+hM5pPyNfdkZDOtOqPY= Authentication-Results: linux.ibm.com; dkim=none (message not signed) header.d=none;linux.ibm.com; dmarc=none action=none header.from=amd.com; Received: from SN6PR12MB2718.namprd12.prod.outlook.com (2603:10b6:805:6f::22) by SN6PR12MB2782.namprd12.prod.outlook.com (2603:10b6:805:73::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4129.28; Wed, 26 May 2021 23:11:55 +0000 Received: from SN6PR12MB2718.namprd12.prod.outlook.com ([fe80::9898:5b48:a062:db94]) by SN6PR12MB2718.namprd12.prod.outlook.com ([fe80::9898:5b48:a062:db94%6]) with mapi id 15.20.4150.023; Wed, 26 May 2021 23:11:55 +0000 From: "Brijesh Singh" To: James Bottomley , Min Xu , Jiewen Yao , Tom Lendacky , Jordan Justen , Laszlo Ersek , Erdem Aktas , Eric Dong , Ray Ni , Rahul Kumar , devel@edk2.groups.io Subject: [PATCH RFC v3 21/22] UefiCpuPkg/MpInitLib: Use SEV-SNP AP Creation NAE event to launch APs Date: Wed, 26 May 2021 18:11:17 -0500 Message-ID: <20210526231118.12946-22-brijesh.singh@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210526231118.12946-1-brijesh.singh@amd.com> References: <20210526231118.12946-1-brijesh.singh@amd.com> X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SA0PR11CA0202.namprd11.prod.outlook.com (2603:10b6:806:1bc::27) To SN6PR12MB2718.namprd12.prod.outlook.com (2603:10b6:805:6f::22) Return-Path: brijesh.singh@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from sbrijesh-desktop.amd.com (165.204.77.1) by SA0PR11CA0202.namprd11.prod.outlook.com (2603:10b6:806:1bc::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4173.21 via Frontend Transport; Wed, 26 May 2021 23:11:54 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: aedaf9e3-881a-43cc-895b-08d9209ba743 X-MS-TrafficTypeDiagnostic: SN6PR12MB2782: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:10000; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: o+kUbVcFBJjTB+juJbMmXGGssmMpOpI5nsw/LFOOJiZbh1EZfyKJmb1prpjQoXbmZaHHlttZu4fSaCRtpkvlIdE4pChinXeyNNYok79V+FcBfSzIvjQd/t62/IS+92bGk3F6i1nKKMXFrVLQJ6mHIb3OEbZQB1v7kuNHP2M7vshzmVid5ZNNMnU9mlJXdqnBuVwiGUJTTbW4py7v/1sW5/6DLRZEptoHb6YZJjHvaECw6IGb1kVl4kNGohZaWMWrB5/APFSX1X1J/lMquHP3WllZqpPO5tkuF3EOVlSaYEXN+qOQz9v1Lmr9OfyLzeo/43M5pSsWBzV2FuMcgNpK3Zo0lL2U1E1bOZzqK1QURwPsqTlK98naNftbIvWjMZJd2HvsYUClGFoW+XzoT+/Ud38MLyuvVn7kWTc4ywJX6ZhZh4wej7dukuUPxnZQz5Q2jdtqKe8eLCoUi1BoJv1y1wpkV7Vp7N9n3VCx52YOaKL+WpsJE/ALkLtpXGUg8UJW+aM3Z+bwsyNbRDYYbl1HzG1pJldDYOqlSVh+H04Kx7o2/e0ATqlAA33hQ9CoNMlDKiloqC/RNHoL2GWVc89cwCWl8ZBH3SzDcqtd6oPID3pxPVUwORmaaFqYTerq9dTQqi6JvJeE+GDshvqqS9Efd+OVftp7HHU2eIUaIX+bngYXbLNmEvAHBRW4GR14t7k8DiXynHTpo2t+9Oco5m4/atEUS6jdLBeTaI2RR1DWX0JN+gVRPeQmKt8tGtYkCF2NXTrtnIntYyefK9pnz7a5A+7fL3X4Ch/EUZ+YTomNN2Q= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SN6PR12MB2718.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(6029001)(4636009)(366004)(39860400002)(346002)(396003)(376002)(136003)(26005)(316002)(5660300002)(8676002)(83380400001)(186003)(38350700002)(16526019)(478600001)(36756003)(30864003)(86362001)(6666004)(7416002)(2616005)(110136005)(44832011)(2906002)(52116002)(66476007)(66556008)(7696005)(921005)(19627235002)(6486002)(8936002)(38100700002)(66946007)(1076003)(956004)(966005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?qsCVdPvFx6i9eFcNNbE/S4WruMPaRRftlcwM71AKGgbLu/DNb0yM9PJGX8vh?= =?us-ascii?Q?BJZFGNTb7lav17HCz34jhJsiak6AOHN7ZV52oszrUb89G8XoPTrEpakoRlEB?= =?us-ascii?Q?psetdcgce3dLDvpDAp+3OQhZF8KOzpH7emBG7Vl/s34+KBSAYacojAaz9GsO?= =?us-ascii?Q?8oCY8PyMTZbb1kUxiRxXqyvprC9bMz5hjsHWcHoTn5P+3F8Jf9gchym43HuZ?= =?us-ascii?Q?Bz1thM1DPQCy3CuUH04B+Ei5S3Afp8QJKvK0IP0WPMQBVmiKCOCrsPgjI3Ik?= =?us-ascii?Q?ewBlINU/hL61WRfMDKAtGu8AZT7hICSuA8mLTk074RIdBiNvh0HqlnlhiuM4?= =?us-ascii?Q?Z77p0nhOlmUSvyOPFMYD23iu0kWC3uUpap14HXbzWvLE1JxRF9JG/xQRYJg0?= =?us-ascii?Q?Kw1YreQ4XFaJdxMnXurI22SRQ2ItxsYSH/4gtRMJJiVFPCI56yprdEh454XZ?= =?us-ascii?Q?E/x/rhXyBIgu25ag1a6Tue5HjDp/cimB5jEJ4gLgc9eA6SRVOCe6P/ks3VV5?= =?us-ascii?Q?YHmNuWKOFIwRDoT//1lD7KrZg2HSYsJ6+/ciYtDyAlknRoEXiEwJ1bf0OxwB?= =?us-ascii?Q?yjaNjFQtF+MWgimqGjHgKPo4O2Uo6w7KOVdimuON+4NUgXX9YQo9uXGmWMjs?= =?us-ascii?Q?2yD6+8y4bKj216HvhhGu3xG7LfCbsj3SGXHYQEt2eO7LA7caLRcUWRw3Jbed?= =?us-ascii?Q?q8IiBY91uckX3+iovEELyj0aTXRfcN8LpehJqAVT2xbB9lx55pi/8q/9j5cR?= =?us-ascii?Q?nwCLoame7SO30FDu2Nu3VSc2YPIVesNYkoz00NN3K30dR1of5RdSBXsSB4AT?= =?us-ascii?Q?6NXxITE1qSSpCd4WQahkIAruzfK0rJnKHfCqA+vbhEL5o457StRz00teqY/s?= =?us-ascii?Q?gxE7O2YTLs/aANU1ytegGatxT9W6LnM0f2Pwv2ysW5imysT+7rN1uls9oUCv?= =?us-ascii?Q?7hMBzXu0zpRxqVfuHesvLzNicCAFEkatE0JdvK9449cdjq8LNbIN7ptVIEpR?= =?us-ascii?Q?/IanqBxpBtwRwt2HRY9obkOQrsuo7IzQ/PzYLobivlCT0r4IAGywHNHM+GI8?= =?us-ascii?Q?k2x4eL2N+d4QjCFLYC1qxkmiZCRcfv6cc3CnH00o2ZVUTuYn5gQQ4ozT9HGX?= =?us-ascii?Q?zUWbFRzZoOIhEktc1FFvlwMAArxPaJlHJNDBwduNKwijuXXghV84JF0nzNZ+?= =?us-ascii?Q?y+ha7HQM+7XV8WH7VSffXQ7BjyW0r+BYqHXSsUrdYfL+OYX16WE1uHPkohQK?= =?us-ascii?Q?ejOZxNntM9uQn3uvzU6coIpOM45kFTNj6QS45r4vuRppTXF258pqgrG/am+z?= =?us-ascii?Q?qBvx9GCZwsWBGbclUWKXJFSo?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: aedaf9e3-881a-43cc-895b-08d9209ba743 X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2718.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 May 2021 23:11:55.0045 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: kQGF5orGD2PUpY1YxeDvihOjm69eT2vcscscVR8UbTAEKHTevhycl+CDk2kHhmL7Wo6iko7yBhGai4XjonznnA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR12MB2782 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Tom Lendacky BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3275 Use the SEV-SNP AP Creation NAE event to create and launch APs under SEV-SNP. This capability will be advertised in the SEV Hypervisor Feature Support PCD (PcdSevEsHypervisorFeatures). Cc: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Signed-off-by: Tom Lendacky --- UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 3 + UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 5 +- UefiCpuPkg/Library/MpInitLib/MpLib.h | 17 ++ UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 11 +- .../MpInitLib/Ia32/SevSnpRmpAdjustInternal.c | 31 ++ UefiCpuPkg/Library/MpInitLib/MpLib.c | 274 ++++++++++++++++-- .../MpInitLib/X64/SevSnpRmpAdjustInternal.c | 44 +++ 7 files changed, 360 insertions(+), 25 deletions(-) create mode 100644 UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustIntern= al.c create mode 100644 UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInterna= l.c diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Lib= rary/MpInitLib/DxeMpInitLib.inf index 48d7dfa4450f..b9ce05e81b54 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -23,9 +23,11 @@ [Defines] =20 [Sources.IA32] Ia32/MpFuncs.nasm + Ia32/SevSnpRmpAdjustInternal.c =20 [Sources.X64] X64/MpFuncs.nasm + X64/SevSnpRmpAdjustInternal.c =20 [Sources.common] MpEqu.inc @@ -72,6 +74,7 @@ [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## = CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## = SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApStatusCheckIntervalInMicroSeconds ## = CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures ## = CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## = CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## = SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## = CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Lib= rary/MpInitLib/PeiMpInitLib.inf index ab8279df596f..35057ac07cbb 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -23,9 +23,11 @@ [Defines] =20 [Sources.IA32] Ia32/MpFuncs.nasm + Ia32/SevSnpRmpAdjustInternal.c =20 [Sources.X64] X64/MpFuncs.nasm + X64/SevSnpRmpAdjustInternal.c =20 [Sources.common] MpEqu.inc @@ -62,10 +64,11 @@ [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate ## SOME= TIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase ## SOME= TIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONS= UMES gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled ## CONS= UMES + gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONS= UMES =20 [Ppis] gEdkiiPeiShadowMicrocodePpiGuid ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 4abaa2243d0a..b49a60ac0ce5 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -15,6 +15,7 @@ =20 #include #include +#include #include #include #include @@ -146,6 +147,7 @@ typedef struct { UINT8 PlatformId; UINT64 MicrocodeEntryAddr; UINT32 MicrocodeRevision; + SEV_ES_SAVE_AREA *SevEsSaveArea; } CPU_AP_DATA; =20 // @@ -289,6 +291,7 @@ struct _CPU_MP_DATA { =20 BOOLEAN SevEsIsEnabled; BOOLEAN SevSnpIsEnabled; + BOOLEAN UseSevEsAPMethod; UINTN SevEsAPBuffer; UINTN SevEsAPResetStackStart; CPU_MP_DATA *NewCpuMpData; @@ -743,5 +746,19 @@ PlatformShadowMicrocode ( IN OUT CPU_MP_DATA *CpuMpData ); =20 +/** + Issue RMPADJUST to adjust the attributes of an SEV-SNP page. + + @param[in] PageAddress + @param[in] VmsaPage + + @return RMPADJUST return value +**/ +UINT32 +SevSnpRmpAdjust ( + IN EFI_PHYSICAL_ADDRESS PageAddress, + IN BOOLEAN VmsaPage + ); + #endif =20 diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/M= pInitLib/DxeMpLib.c index 7839c249760e..1e3e71766611 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -88,7 +88,12 @@ GetWakeupBuffer ( EFI_PHYSICAL_ADDRESS StartAddress; EFI_MEMORY_TYPE MemoryType; =20 - if (PcdGetBool (PcdSevEsIsEnabled)) { + // + // An SEV-ES-only guest requires the memory to be reserved. SEV-SNP, whi= ch + // is also considered SEV-ES, uses a different AP startup method, though= , + // which does not have the same requirement. + // + if (PcdGetBool (PcdSevEsIsEnabled) && !PcdGetBool (PcdSevSnpIsEnabled)) = { MemoryType =3D EfiReservedMemoryType; } else { MemoryType =3D EfiBootServicesData; @@ -356,7 +361,7 @@ RelocateApLoop ( MpInitLibWhoAmI (&ProcessorNumber); CpuMpData =3D GetCpuMpData (); MwaitSupport =3D IsMwaitSupport (); - if (CpuMpData->SevEsIsEnabled) { + if (CpuMpData->UseSevEsAPMethod) { StackStart =3D CpuMpData->SevEsAPResetStackStart; } else { StackStart =3D mReservedTopOfApStack; @@ -405,7 +410,7 @@ MpInitChangeApLoopCallback ( CpuPause (); } =20 - if (CpuMpData->SevEsIsEnabled && (CpuMpData->WakeupBuffer !=3D (UINTN) -= 1)) { + if (CpuMpData->UseSevEsAPMethod && (CpuMpData->WakeupBuffer !=3D (UINTN)= -1)) { // // There are APs present. Re-use reserved memory area below 1MB from // WakeupBuffer as the area to be used for transitioning to 16-bit mod= e diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c b/= UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c new file mode 100644 index 000000000000..167628b696f2 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/SevSnpRmpAdjustInternal.c @@ -0,0 +1,31 @@ +/** @file + + RMPADJUST helper function. + + Copyright (c) 2021, AMD Incorporated. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" + +/** + Issue RMPADJUST to adjust the attributes of an SEV-SNP page. + + @param[in] PageAddress + @param[in] VmsaPage + + @return RMPADJUST return value +**/ +UINT32 +SevSnpRmpAdjust ( + IN EFI_PHYSICAL_ADDRESS PageAddress, + IN BOOLEAN VmsaPage + ) +{ + // + // RMPADJUST is not supported in 32-bit mode + // + return RETURN_UNSUPPORTED; +} diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/MpLib.c index 7cbcce101414..5a06e21a2830 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -15,7 +15,6 @@ =20 EFI_GUID mCpuInitMpLibHobGuid =3D CPU_INIT_MP_LIB_HOB_GUID; =20 - /** The function will check if BSP Execute Disable is enabled. =20 @@ -297,8 +296,8 @@ GetApLoopMode ( =20 if (PcdGetBool (PcdSevEsIsEnabled)) { // - // For SEV-ES, force AP in Hlt-loop mode in order to use the GHCB - // protocol for starting APs + // For SEV-ES (SEV-SNP is also considered SEV-ES), force AP in Hlt-l= oop + // mode in order to use the GHCB protocol for starting APs // ApLoopMode =3D ApInHltLoop; } @@ -869,7 +868,7 @@ ApWakeupFunction ( // to allow the APs to issue an AP_RESET_HOLD before the BSP possibl= y // performs another INIT-SIPI-SIPI sequence. // - if (!CpuMpData->SevEsIsEnabled) { + if (!CpuMpData->UseSevEsAPMethod) { InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->Nu= mApsExecuting); } } @@ -883,7 +882,7 @@ ApWakeupFunction ( // while (TRUE) { DisableInterrupts (); - if (CpuMpData->SevEsIsEnabled) { + if (CpuMpData->UseSevEsAPMethod) { MSR_SEV_ES_GHCB_REGISTER Msr; GHCB *Ghcb; UINT64 Status; @@ -1167,9 +1166,11 @@ GetApResetVectorSize ( =20 // // The AP reset stack is only used by SEV-ES guests. Do not add to the - // allocation if SEV-ES is not enabled. + // allocation if SEV-ES is not enabled. An SEV-SNP guest is also conside= red + // an SEV-ES guest, but uses a different method of AP startup, eliminati= ng + // the need for the allocation. // - if (PcdGetBool (PcdSevEsIsEnabled)) { + if (PcdGetBool (PcdSevEsIsEnabled) && !PcdGetBool (PcdSevSnpIsEnabled)) = { // // Stack location is based on APIC ID, so use the total number of // processors for calculating the total stack area. @@ -1231,7 +1232,7 @@ FreeResetVector ( // perform the restore as this will overwrite memory which has data // needed by SEV-ES. // - if (!CpuMpData->SevEsIsEnabled) { + if (!CpuMpData->UseSevEsAPMethod) { RestoreWakeupBuffer (CpuMpData); } } @@ -1248,7 +1249,7 @@ AllocateSevEsAPMemory ( { if (CpuMpData->SevEsAPBuffer =3D=3D (UINTN) -1) { CpuMpData->SevEsAPBuffer =3D - CpuMpData->SevEsIsEnabled ? GetSevEsAPMemory () : 0; + CpuMpData->UseSevEsAPMethod ? GetSevEsAPMemory () : 0; } } =20 @@ -1301,6 +1302,222 @@ SetSevEsJumpTable ( JmpFar->Segment =3D (UINT16) (SipiVector >> 4); } =20 +/** + Create an SEV-SNP AP save area (VMSA) for use in running the vCPU. + + @param[in] CpuMpData Pointer to CPU MP Data + @param[in] CpuData Pointer to CPU AP Data + @param[in] ApicId APIC ID of the vCPU +**/ +STATIC +VOID +SevSnpCreateSaveArea ( + IN CPU_MP_DATA *CpuMpData, + IN CPU_AP_DATA *CpuData, + UINT32 ApicId + ) +{ + SEV_ES_SAVE_AREA *SaveArea; + IA32_CR0 ApCr0; + IA32_CR0 ResetCr0; + IA32_CR4 ApCr4; + IA32_CR4 ResetCr4; + UINTN StartIp; + UINT8 SipiVector; + UINT32 RmpAdjustStatus; + UINT64 VmgExitStatus; + MSR_SEV_ES_GHCB_REGISTER Msr; + GHCB *Ghcb; + BOOLEAN InterruptState; + UINT64 ExitInfo1; + UINT64 ExitInfo2; + + // + // Allocate a single page for the SEV-ES Save Area and initialize it. + // + SaveArea =3D AllocateReservedPages (1); + if (!SaveArea) { + return; + } + ZeroMem (SaveArea, EFI_PAGE_SIZE); + + // + // Propogate the CR0.NW and CR0.CD setting to the AP + // + ResetCr0.UintN =3D 0x00000010; + ApCr0.UintN =3D CpuData->VolatileRegisters.Cr0; + if (ApCr0.Bits.NW) { + ResetCr0.Bits.NW =3D 1; + } + if (ApCr0.Bits.CD) { + ResetCr0.Bits.CD =3D 1; + } + + // + // Propagate the CR4.MCE setting to the AP + // + ResetCr4.UintN =3D 0; + ApCr4.UintN =3D CpuData->VolatileRegisters.Cr4; + if (ApCr4.Bits.MCE) { + ResetCr4.Bits.MCE =3D 1; + } + + // + // Convert the start IP into a SIPI Vector + // + StartIp =3D CpuMpData->MpCpuExchangeInfo->BufferStart; + SipiVector =3D (UINT8) (StartIp >> 12); + + // + // Set the CS:RIP value based on the start IP + // + SaveArea->Cs.Base =3D SipiVector << 12; + SaveArea->Cs.Selector =3D SipiVector << 8; + SaveArea->Cs.Limit =3D 0xFFFF; + SaveArea->Cs.Attributes.Bits.Present =3D 1; + SaveArea->Cs.Attributes.Bits.Sbit =3D 1; + SaveArea->Cs.Attributes.Bits.Type =3D SEV_ES_RESET_CODE_SEGMENT_TYPE; + SaveArea->Rip =3D StartIp & 0xFFF; + + // + // Set the remaining values as defined in APM for INIT + // + SaveArea->Ds.Limit =3D 0xFFFF; + SaveArea->Ds.Attributes.Bits.Present =3D 1; + SaveArea->Ds.Attributes.Bits.Sbit =3D 1; + SaveArea->Ds.Attributes.Bits.Type =3D SEV_ES_RESET_DATA_SEGMENT_TYPE; + SaveArea->Es =3D SaveArea->Ds; + SaveArea->Fs =3D SaveArea->Ds; + SaveArea->Gs =3D SaveArea->Ds; + SaveArea->Ss =3D SaveArea->Ds; + + SaveArea->Gdtr.Limit =3D 0xFFFF; + SaveArea->Ldtr.Limit =3D 0xFFFF; + SaveArea->Ldtr.Attributes.Bits.Present =3D 1; + SaveArea->Ldtr.Attributes.Bits.Type =3D SEV_ES_RESET_LDT_TYPE; + SaveArea->Idtr.Limit =3D 0xFFFF; + SaveArea->Tr.Limit =3D 0xFFFF; + SaveArea->Ldtr.Attributes.Bits.Present =3D 1; + SaveArea->Ldtr.Attributes.Bits.Type =3D SEV_ES_RESET_TSS_TYPE; + + SaveArea->Efer =3D 0x1000; + SaveArea->Cr4 =3D ResetCr4.UintN; + SaveArea->Cr0 =3D ResetCr0.UintN; + SaveArea->Dr7 =3D 0x0400; + SaveArea->Dr6 =3D 0xFFFF0FF0; + SaveArea->Rflags =3D 0x0002; + SaveArea->GPat =3D 0x0007040600070406ULL; + SaveArea->XCr0 =3D 0x0001; + SaveArea->Mxcsr =3D 0x1F80; + SaveArea->X87Ftw =3D 0x5555; + SaveArea->X87Fcw =3D 0x0040; + + // + // Set the SEV-SNP specific fields for the save area: + // VMPL - always VMPL0 + // SEV_FEATURES - equivalent to the SEV_STATUS MSR right shifted 2 bit= s + // + SaveArea->Vmpl =3D 0; + SaveArea->SevFeatures =3D AsmReadMsr64 (MSR_SEV_STATUS) >> 2; + + // + // To turn the page into a recognized VMSA page, issue RMPADJUST: + // Target VMPL but numerically higher than current VMPL + // Target PermissionMask is not used + // + RmpAdjustStatus =3D SevSnpRmpAdjust ( + (EFI_PHYSICAL_ADDRESS) (UINTN) SaveArea, + TRUE + ); + ASSERT (RmpAdjustStatus =3D=3D 0); + + ExitInfo1 =3D (UINT64) ApicId << 32; + ExitInfo1 |=3D SVM_VMGEXIT_SNP_AP_CREATE; + ExitInfo2 =3D (UINT64) (UINTN) SaveArea; + + Msr.GhcbPhysicalAddress =3D AsmReadMsr64 (MSR_SEV_ES_GHCB); + Ghcb =3D Msr.Ghcb; + + VmgInit (Ghcb, &InterruptState); + Ghcb->SaveArea.Rax =3D SaveArea->SevFeatures; + VmgSetOffsetValid (Ghcb, GhcbRax); + VmgExitStatus =3D VmgExit ( + Ghcb, + SVM_EXIT_SNP_AP_CREATION, + ExitInfo1, + ExitInfo2 + ); + VmgDone (Ghcb, InterruptState); + + ASSERT (VmgExitStatus =3D=3D 0); + if (VmgExitStatus !=3D 0) { + RmpAdjustStatus =3D SevSnpRmpAdjust ( + (EFI_PHYSICAL_ADDRESS) (UINTN) SaveArea, + FALSE + ); + if (RmpAdjustStatus =3D=3D 0) { + FreePages (SaveArea, 1); + } else { + DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed, leaking VMSA page\n"= )); + } + + SaveArea =3D NULL; + } + + if (CpuData->SevEsSaveArea) { + RmpAdjustStatus =3D SevSnpRmpAdjust ( + (EFI_PHYSICAL_ADDRESS) (UINTN) CpuData->SevEsSaveA= rea, + FALSE + ); + if (RmpAdjustStatus =3D=3D 0) { + FreePages (CpuData->SevEsSaveArea, 1); + } else { + DEBUG ((DEBUG_INFO, "SEV-SNP: RMPADJUST failed, leaking VMSA page\n"= )); + } + } + + CpuData->SevEsSaveArea =3D SaveArea; +} + +/** + Create SEV-SNP APs. + + @param[in] CpuMpData Pointer to CPU MP Data + @param[in] ProcessorNumber The handle number of specified processor + (-1 for all APs) +**/ +STATIC +VOID +SevSnpCreateAP ( + IN CPU_MP_DATA *CpuMpData, + IN INTN ProcessorNumber + ) +{ + CPU_INFO_IN_HOB *CpuInfoInHob; + CPU_AP_DATA *CpuData; + UINTN Index; + UINT32 ApicId; + + ASSERT (CpuMpData->MpCpuExchangeInfo->BufferStart < 0x100000); + + CpuInfoInHob =3D (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob; + + if (ProcessorNumber < 0) { + for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { + if (Index !=3D CpuMpData->BspNumber) { + CpuData =3D &CpuMpData->CpuData[Index]; + ApicId =3D CpuInfoInHob[Index].ApicId, + SevSnpCreateSaveArea (CpuMpData, CpuData, ApicId); + } + } + } else { + Index =3D (UINTN) ProcessorNumber; + CpuData =3D &CpuMpData->CpuData[Index]; + ApicId =3D CpuInfoInHob[ProcessorNumber].ApicId, + SevSnpCreateSaveArea (CpuMpData, CpuData, ApicId); + } +} + /** This function will be called by BSP to wakeup AP. =20 @@ -1332,7 +1549,7 @@ WakeUpAP ( ResetVectorRequired =3D FALSE; =20 if (CpuMpData->WakeUpByInitSipiSipi || - CpuMpData->InitFlag !=3D ApInitDone) { + CpuMpData->InitFlag !=3D ApInitDone) { ResetVectorRequired =3D TRUE; AllocateResetVector (CpuMpData); AllocateSevEsAPMemory (CpuMpData); @@ -1373,7 +1590,7 @@ WakeUpAP ( } if (ResetVectorRequired) { // - // For SEV-ES, the initial AP boot address will be defined by + // For SEV-ES and SEV-SNP, the initial AP boot address will be defin= ed by // PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address // from the original INIT-SIPI-SIPI. // @@ -1383,8 +1600,14 @@ WakeUpAP ( =20 // // Wakeup all APs + // Must use the INIT-SIPI-SIPI method for initial configuration in + // order to obtain the APIC ID. // - SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart= ); + if (CpuMpData->SevSnpIsEnabled && CpuMpData->InitFlag !=3D ApInitCon= fig) { + SevSnpCreateAP (CpuMpData, -1); + } else { + SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferSta= rt); + } } if (CpuMpData->InitFlag =3D=3D ApInitConfig) { if (PcdGet32 (PcdCpuBootLogicalProcessorNumber) > 0) { @@ -1474,7 +1697,7 @@ WakeUpAP ( CpuInfoInHob =3D (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob= ; =20 // - // For SEV-ES, the initial AP boot address will be defined by + // For SEV-ES and SEV-SNP, the initial AP boot address will be defin= ed by // PcdSevEsWorkAreaBase. The Segment/Rip must be the jump address // from the original INIT-SIPI-SIPI. // @@ -1482,10 +1705,14 @@ WakeUpAP ( SetSevEsJumpTable (ExchangeInfo->BufferStart); } =20 - SendInitSipiSipi ( - CpuInfoInHob[ProcessorNumber].ApicId, - (UINT32) ExchangeInfo->BufferStart - ); + if (CpuMpData->SevSnpIsEnabled && CpuMpData->InitFlag !=3D ApInitCon= fig) { + SevSnpCreateAP (CpuMpData, (INTN) ProcessorNumber); + } else { + SendInitSipiSipi ( + CpuInfoInHob[ProcessorNumber].ApicId, + (UINT32) ExchangeInfo->BufferStart + ); + } } // // Wait specified AP waken up @@ -2016,10 +2243,15 @@ MpInitLibInitialize ( CpuMpData->CpuData =3D (CPU_AP_DATA *) (CpuMpData + 1); CpuMpData->CpuInfoInHob =3D (UINT64) (UINTN) (CpuMpData->CpuData + M= axLogicalProcessorNumber); InitializeSpinLock(&CpuMpData->MpLock); - CpuMpData->SevEsIsEnabled =3D PcdGetBool (PcdSevEsIsEnabled); - CpuMpData->SevSnpIsEnabled =3D PcdGetBool (PcdSevSnpIsEnabled); - CpuMpData->SevEsAPBuffer =3D (UINTN) -1; - CpuMpData->GhcbBase =3D PcdGet64 (PcdGhcbBase); + CpuMpData->SevEsIsEnabled =3D PcdGetBool (PcdSevEsIsEnabled); + CpuMpData->SevSnpIsEnabled =3D PcdGetBool (PcdSevSnpIsEnabled); + CpuMpData->SevEsAPBuffer =3D (UINTN) -1; + CpuMpData->GhcbBase =3D PcdGet64 (PcdGhcbBase); + CpuMpData->UseSevEsAPMethod =3D CpuMpData->SevEsIsEnabled && !CpuMpData-= >SevSnpIsEnabled; + + if (CpuMpData->SevSnpIsEnabled) { + ASSERT ((PcdGet64 (PcdGhcbHypervisorFeatures) & GHCB_HV_FEATURES_SNP_A= P_CREATE) =3D=3D GHCB_HV_FEATURES_SNP_AP_CREATE); + } =20 // // Make sure no memory usage outside of the allocated buffer. diff --git a/UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c b/U= efiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c new file mode 100644 index 000000000000..0716a4623e38 --- /dev/null +++ b/UefiCpuPkg/Library/MpInitLib/X64/SevSnpRmpAdjustInternal.c @@ -0,0 +1,44 @@ +/** @file + + RMPADJUST helper function. + + Copyright (c) 2021, AMD Incorporated. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "MpLib.h" + +/** + Issue RMPADJUST to adjust the attributes of an SEV-SNP page. + + @param[in] PageAddress + @param[in] VmsaPage + + @return RMPADJUST return value +**/ +UINT32 +SevSnpRmpAdjust ( + IN EFI_PHYSICAL_ADDRESS PageAddress, + IN BOOLEAN VmsaPage + ) +{ + UINT64 Rdx; + UINT8 Vmpl; + UINT8 PermissionMask; + + // + // Use the highest VMPL level. + // + PermissionMask =3D 0; + Vmpl =3D RMPADJUST_VMPL_MAX; + + Rdx =3D (Vmpl & RMPADJUST_VMPL_MASK) << RMPADJUST_VMPL_SHIFT; + Rdx |=3D (PermissionMask & RMPADJUST_PERMISSION_MASK_MASK) << RMPADJUST_= PERMISSION_MASK_SHIFT; + if (VmsaPage) { + Rdx |=3D RMPADJUST_VMSA_PAGE_BIT; + } + + return AsmRmpAdjust ((UINT64) PageAddress, 0, Rdx); +} --=20 2.17.1