From nobody Mon Dec 23 11:12:00 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 15199491115424.938866103875625; Thu, 1 Mar 2018 16:05:11 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 5F4232255D6F2; Thu, 1 Mar 2018 15:58:31 -0800 (PST) Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 9C9DB2255D6EB for ; Thu, 1 Mar 2018 15:58:29 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F29368182D2E; Fri, 2 Mar 2018 00:04:37 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-4.rdu2.redhat.com [10.10.120.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1860B10B0F24; Fri, 2 Mar 2018 00:04:36 +0000 (UTC) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org From: Laszlo Ersek To: edk2-devel-01 Date: Fri, 2 Mar 2018 01:04:08 +0100 Message-Id: <20180302000408.14201-21-lersek@redhat.com> In-Reply-To: <20180302000408.14201-1-lersek@redhat.com> References: <20180302000408.14201-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 02 Mar 2018 00:04:38 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 02 Mar 2018 00:04:38 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'lersek@redhat.com' RCPT:'' Subject: [edk2] [PATCH 20/20] OvmfPkg/AmdSevDxe: decrypt the pages of the initial SMRAM save state map X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jordan Justen , Brijesh Singh , Ard Biesheuvel MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Based on the following patch from Brijesh Singh : [PATCH v2 1/2] OvmfPkg/AmdSevDxe: Clear the C-bit from SMM Saved State http://mid.mail-archive.com/20180228161415.28723-2-brijesh.singh@amd.com https://lists.01.org/pipermail/edk2-devel/2018-February/022016.html Original commit message from Brijesh: > When OVMF is built with SMM, SMMSaved State area (SMM_DEFAULT_SMBASE + > SMRAM_SAVE_STATE_MAP_OFFSET) contains data which need to be accessed by > both guest and hypervisor. Since the data need to be accessed by both > hence we must map the SMMSaved State area as unencrypted (i.e C-bit > cleared). > > This patch clears the SavedStateArea address before SMBASE relocation. > Currently, we do not clear the SavedStateArea address after SMBASE is > relocated due to the following reasons: > > 1) Guest BIOS never access the relocated SavedStateArea. > > 2) The C-bit works on page-aligned address, but the SavedStateArea > address is not a page-aligned. Theoretically, we could roundup the > address and clear the C-bit of aligned address but looking carefully we > found that some portion of the page contains code -- which will causes a > bigger issue for the SEV guest. When SEV is enabled, all the code must > be encrypted otherwise hardware will cause trap. Changes by Laszlo: - separate AmdSevDxe bits from SmmCpuFeaturesLib bits; - spell out PcdLib dependency with #include and in LibraryClasses; - replace (SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET) calculation with call to new MemEncryptSevLocateInitialSmramSaveStateMapPages() function; - consequently, pass page-aligned BaseAddress to MemEncryptSevClearPageEncMask(); - zero the pages before clearing the C-bit; - pass Flush=3DTRUE to MemEncryptSevClearPageEncMask(); - harden the treatment of MemEncryptSevClearPageEncMask() failure. Cc: Ard Biesheuvel Cc: Brijesh Singh Cc: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek --- OvmfPkg/AmdSevDxe/AmdSevDxe.inf | 6 +++ OvmfPkg/AmdSevDxe/AmdSevDxe.c | 53 ++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.= inf index 3aff7e292053..b7e7da002d5e 100644 --- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf +++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf @@ -15,28 +15,34 @@ # #**/ =20 [Defines] INF_VERSION =3D 1.25 BASE_NAME =3D AmdSevDxe FILE_GUID =3D 2ec9da37-ee35-4de9-86c5-6d9a81dc38a7 MODULE_TYPE =3D DXE_DRIVER VERSION_STRING =3D 1.0 ENTRY_POINT =3D AmdSevDxeEntryPoint =20 [Sources] AmdSevDxe.c =20 [Packages] MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec =20 [LibraryClasses] + BaseLib + BaseMemoryLib DebugLib DxeServicesTableLib MemEncryptSevLib MemoryAllocationLib + PcdLib UefiDriverEntryPoint =20 [Depex] TRUE + +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c index 8f02d0627e02..c697580ad5b8 100644 --- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c +++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c @@ -1,42 +1,45 @@ /** @file =20 AMD Sev Dxe driver. This driver is dispatched early in DXE, due to being= list in APRIORI. It clears C-bit from MMIO and NonExistent Memory space when = SEV is enabled. =20 Copyright (c) 2017, AMD Inc. All rights reserved.
=20 This program and the accompanying materials are licensed and made availa= ble under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php =20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WI= THOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. =20 **/ =20 +#include +#include #include #include #include #include +#include =20 EFI_STATUS EFIAPI AmdSevDxeEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_GCD_MEMORY_SPACE_DESCRIPTOR *AllDescMap; UINTN NumEntries; UINTN Index; =20 // // Do nothing when SEV is not enabled // if (!MemEncryptSevIsEnabled ()) { return EFI_UNSUPPORTED; } =20 @@ -51,22 +54,72 @@ AmdSevDxeEntryPoint ( if (!EFI_ERROR (Status)) { for (Index =3D 0; Index < NumEntries; Index++) { CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc; =20 Desc =3D &AllDescMap[Index]; if (Desc->GcdMemoryType =3D=3D EfiGcdMemoryTypeMemoryMappedIo || Desc->GcdMemoryType =3D=3D EfiGcdMemoryTypeNonExistent) { Status =3D MemEncryptSevClearPageEncMask ( 0, Desc->BaseAddress, EFI_SIZE_TO_PAGES (Desc->Length), FALSE ); ASSERT_EFI_ERROR (Status); } } =20 FreePool (AllDescMap); } =20 + // + // When SMM is enabled, clear the C-bit from SMM Saved State Area + // + // NOTES: The SavedStateArea address cleared here is before SMBASE + // relocation. Currently, we do not clear the SavedStateArea address aft= er + // SMBASE is relocated due to the following reasons: + // + // 1) Guest BIOS never access the relocated SavedStateArea. + // + // 2) The C-bit works on page-aligned address, but the SavedStateArea + // address is not a page-aligned. Theoretically, we could roundup the ad= dress + // and clear the C-bit of aligned address but looking carefully we found + // that some portion of the page contains code -- which will causes a bi= gger + // issues for SEV guest. When SEV is enabled, all the code must be encry= pted + // otherwise hardware will cause trap. + // + // We restore the C-bit for this SMM Saved State Area after SMBASE reloc= ation + // is completed (See OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib= .c). + // + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINTN MapPagesBase; + UINTN MapPagesCount; + + Status =3D MemEncryptSevLocateInitialSmramSaveStateMapPages ( + &MapPagesBase, + &MapPagesCount + ); + ASSERT_EFI_ERROR (Status); + + // + // Although these pages were set aside (i.e., allocated) by PlatformPe= i, we + // could be after a warm reboot from the OS. Don't leak any stale OS d= ata + // to the hypervisor. + // + ZeroMem ((VOID *)MapPagesBase, EFI_PAGES_TO_SIZE (MapPagesCount)); + + Status =3D MemEncryptSevClearPageEncMask ( + 0, // Cr3BaseAddress -- use current CR3 + MapPagesBase, // BaseAddress + MapPagesCount, // NumPages + TRUE // Flush + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: MemEncryptSevClearPageEncMask(): %r\n", + __FUNCTION__, Status)); + ASSERT (FALSE); + CpuDeadLoop (); + } + } + return EFI_SUCCESS; } --=20 2.14.1.3.gb7cf6e02401b _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel