From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM03-DM3-obe.outbound.protection.outlook.com (mail-dm3nam03on060d.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe49::60d]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 6066A803B1 for ; Fri, 24 Mar 2017 07:39:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=IjewadYKPiIbs01xsEoUF7BfVu+LsYOLSliGMKQLYTg=; b=CR64Xw4ct3Fg3u+yvv1VLqZtcxZuhvm0oOwa6VUoovGDrAXlynl8NScwaP9gYnLzLTilwJPfY5M8IwKivUd1SEnnwmkdR5lTfRsMEdDxVpjtkLoEusEKaRsY2Wv33ag/ZAb7BjIaCBC5tzRNX4Bcq2+zoFZZ5PlOPUX75inErhQ= Received: from DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) by BN6PR1201MB0132.namprd12.prod.outlook.com (10.174.114.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.977.11; Fri, 24 Mar 2017 14:39:49 +0000 Received: from DM5PR12MB1243.namprd12.prod.outlook.com ([10.168.237.22]) by DM5PR12MB1243.namprd12.prod.outlook.com ([10.168.237.22]) with mapi id 15.01.0977.021; Fri, 24 Mar 2017 14:39:48 +0000 From: "Duran, Leo" To: "'Zeng, Star'" , "Yao, Jiewen" , "edk2-devel@ml01.01.org" CC: "Tian, Feng" , "Singh, Brijesh" Thread-Topic: [PATCH] MdeModulePkg/Core/Dxe: Clear SEV mask on MMIO regions Thread-Index: AQHSpEmQD9EKUCBCTk+xjMUR38haG6GjSn2AgABLIYCAAAfmgIAAAneAgABv9sA= Date: Fri, 24 Mar 2017 14:39:48 +0000 Message-ID: References: <1490323887-9686-1-git-send-email-leo.duran@amd.com> <1490323887-9686-2-git-send-email-leo.duran@amd.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B84DACA@shsmsx102.ccr.corp.intel.com> <74D8A39837DF1E4DA445A8C0B3885C503A9139A8@shsmsx102.ccr.corp.intel.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B84EB12@shsmsx102.ccr.corp.intel.com> In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB0483103B84EB12@shsmsx102.ccr.corp.intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=amd.com; x-originating-ip: [165.204.77.1] x-microsoft-exchange-diagnostics: 1; BN6PR1201MB0132; 7:uXPPanJ02fLp2P4l83vnTvzMgs/bLVzGazwarGmttwnwvKvKwibP9+jx95+oS1KD8A2SQHyhjEKw4/KpdAZX9ws8m1qiq9HLyp2imTW1/e0Zd48kzq0E/9213VFJ5dBYH417oYFiSQPiXaxlPFHfdb3dx5Wg0Kzm3GtmK/3dgKU4qnWyV4/CrI3y7OCyjXswo4h39PgzjEUVR20h4Rz9HP1vtmY5vrIMjaT0TinidQcmvEXD9BgKxFGxIoJ13EaIoXYC3FOWwtaoB1TCP8FG2wDNZSNbXWovfrjt47r4bt9eP5hYiv3EJJ3m4r024mK7+yjk9Kjz6cjVWBcu3ZO+vg==; 20:KbsaO0dDqoWZ0Nldpjykm/AyNtjvQaSq3/6Y8E/7QwZboP3f3jTw4i893vOLZkKsQAO7KnH3U3d7DoA3THdFoQu2C5XVrJ75lWKoKfxx7TSTNpfYFkTVnek3DeMgd/9j07pPayJvjCYt1mEkwk6UnYmOcOqRA/ueYk0Uh/qfFQ44uJHEgBTtHGS4XULK+/oC2F6tGz74mGkvMqsqtimPo4ffjjyrIDqbZ4UD8bXc04sWmAm7iaCULMicju7qlJsP x-forefront-antispam-report: SFV:SKI; SCL:-1SFV:NSPM; SFS:(10009020)(6009001)(39450400003)(39840400002)(39410400002)(39850400002)(39860400002)(51914003)(377454003)(15188155005)(229853002)(6246003)(8936002)(16799955002)(93886004)(5660300001)(86362001)(122556002)(305945005)(3846002)(3280700002)(7736002)(2900100001)(66066001)(2906002)(102836003)(189998001)(4326008)(38730400002)(33656002)(6116002)(966004)(53946003)(2501003)(3660700001)(6436002)(50986999)(53376002)(81166006)(54356999)(76176999)(7696004)(6306002)(9686003)(53936002)(77096006)(74316002)(25786009)(8676002)(54906002)(6506006)(55016002)(2950100002)(99286003)(579004)(559001)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:BN6PR1201MB0132; H:DM5PR12MB1243.namprd12.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; x-ms-office365-filtering-correlation-id: 9e78d623-736e-4d1e-91c7-08d472c39f75 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254075)(48565401081); SRVR:BN6PR1201MB0132; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(767451399110)(162533806227266)(228905959029699); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026)(6041248)(20161123562025)(20161123558025)(20161123555025)(20161123560025)(20161123564025)(6072148); SRVR:BN6PR1201MB0132; BCL:0; PCL:0; RULEID:; SRVR:BN6PR1201MB0132; x-forefront-prvs: 0256C18696 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Mar 2017 14:39:48.3982 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR1201MB0132 Subject: Re: [PATCH] MdeModulePkg/Core/Dxe: Clear SEV mask on MMIO regions X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Mar 2017 14:39:52 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Jiewen, Star, Thanks for the prompt & detailed review. I'll certainly consider your feedb= ack. Leo. > -----Original Message----- > From: Zeng, Star [mailto:star.zeng@intel.com] > Sent: Friday, March 24, 2017 2:57 AM > To: Yao, Jiewen ; Duran, Leo > ; edk2-devel@ml01.01.org > Cc: Tian, Feng ; Singh, Brijesh > ; Zeng, Star > Subject: RE: [PATCH] MdeModulePkg/Core/Dxe: Clear SEV mask on MMIO > regions >=20 > Jiewen, >=20 > I like the solution you proposed. :) >=20 > Thanks, > Star > -----Original Message----- > From: Yao, Jiewen > Sent: Friday, March 24, 2017 3:49 PM > To: Zeng, Star ; Leo Duran ; > edk2-devel@ml01.01.org > Cc: Tian, Feng ; Brijesh Singh > ; Zeng, Star > Subject: RE: [PATCH] MdeModulePkg/Core/Dxe: Clear SEV mask on MMIO > regions >=20 > Hi Duran > I have a little concern about this patch, because we do not introduce any= CPU > specific thing in DxeCore so far. >=20 > I think the basic requirement for SEV is to encrypt system memory, but no= t > MMIO. (Please correct me if I am wrong.) >=20 > If that is the case, I would like to propose another solution for your > consideration. >=20 > 1) In PEI phage, a platform should report PI resource description hob to > describe system resource, including system memory, and MMIO. >=20 > 2) The DxeIpl can be updated to parse the PI resource description hob to = get > all system memory (DRAM) and MMIO. The DxeIpl can setup page table > based upon the SEV policy on DRAM/MMIO. I think we should set SEV mask > for DRAM (no matter it is tested or untested), but always clear SEV mask = for > MMIO and all rest. >=20 > 3) When DxeCore gets control, the page table only has DRAM as encrypted, > all rest MMIO as decrypted. >=20 > 4) In DXE phase, if a platform module wants to add new DRAM resource, the > entity which submit ADD request needs to update page table. (NOTE: If a > platform just want to convert an UNTESTED DRAM to a TESTED DRAM, this > entity does not update page table, because it is already encrypted in Dxe= Ipl.) > If a platform module wants to add new MMIO resource, this entity does not > update table, because it is already decrypted in DxeIpl.) >=20 > Can above flow meet the AMD SEV requirement? >=20 > Thank you > Yao Jiewen >=20 >=20 >=20 > > -----Original Message----- > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of > > Zeng, Star > > Sent: Friday, March 24, 2017 3:20 PM > > To: Leo Duran ; edk2-devel@ml01.01.org > > Cc: Tian, Feng ; Brijesh Singh > > ; Zeng, Star > > Subject: Re: [edk2] [PATCH] MdeModulePkg/Core/Dxe: Clear SEV mask on > > MMIO regions > > > > I have comments below. > > > > 1. Why need to call ConvertEncryptionOnAddressRange() at > > GCD_FREE_MEMORY_OPERATION case? > GCD_FREE_MEMORY_OPERATION does not > > change the Entry->GcdMemoryType. > > 2. I think it is better to use if (Entry->GcdMemoryType =3D=3D > > EfiGcdMemoryTypeMemoryMappedIo) instead of if (Entry->Capabilities & > > EFI_MEMORY_PORT_IO) for GCD_REMOVE_MEMORY_OPERATION case. > > 3. Why need to use PAGING_4K_ADDRESS_MASK_64 in GcdHelper.c? Why > need > > to define PAGING_2M_ADDRESS_MASK_64? > > 4. Why need to unmask Cr3 like below in GcdHelper.c? The PageTables is > > not masked at DxeIpl before written to CR3. Only the table entry needs > > to be unmask in GcdHelper.c, right? > > GcdHelper.c: Cr3 & ~AddressEncMask > > DxeIpl: AsmWriteCr3 (PageTables); > > 5. Do you need to add dummy GcdHelper.c for other archs? Do you need > > to put GcdHelperCommon.c and GcdHelper.h under the arch IA32 and X64 > > as other archs do not need them? > > > > > > Thanks, > > Star > > -----Original Message----- > > From: Leo Duran [mailto:leo.duran@amd.com] > > Sent: Friday, March 24, 2017 10:51 AM > > To: edk2-devel@ml01.01.org > > Cc: Leo Duran ; Tian, Feng ; > > Zeng, Star ; Brijesh Singh > > > > Subject: [PATCH] MdeModulePkg/Core/Dxe: Clear SEV mask on MMIO > regions > > > > This patch intercepts MMIO configuration in the GCD module to ensure > > those regions are unmasked. > > > > Cc: Feng Tian > > Cc: Star Zeng > > Cc: Brijesh Singh > > Contributed-under: TianoCore Contribution Agreement 1.0 > > Signed-off-by: Leo Duran > > --- > > MdeModulePkg/Core/Dxe/DxeMain.inf | 11 ++ > > MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 28 ++++++ > > MdeModulePkg/Core/Dxe/Gcd/GcdHelper.h | 151 > > ++++++++++++++++++++++++++++ > > MdeModulePkg/Core/Dxe/Gcd/GcdHelperCommon.c | 120 > > ++++++++++++++++++++++ > MdeModulePkg/Core/Dxe/Gcd/Ia32/GcdHelper.c > > | 115 +++++++++++++++++++++ > > MdeModulePkg/Core/Dxe/Gcd/X64/GcdHelper.c | 129 > > ++++++++++++++++++++++++ > > 6 files changed, 554 insertions(+) > > create mode 100644 MdeModulePkg/Core/Dxe/Gcd/GcdHelper.h > > create mode 100644 > MdeModulePkg/Core/Dxe/Gcd/GcdHelperCommon.c > > create mode 100644 MdeModulePkg/Core/Dxe/Gcd/Ia32/GcdHelper.c > > create mode 100644 MdeModulePkg/Core/Dxe/Gcd/X64/GcdHelper.c > > > > diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf > > b/MdeModulePkg/Core/Dxe/DxeMain.inf > > index 30d5984..183d1e7 100644 > > --- a/MdeModulePkg/Core/Dxe/DxeMain.inf > > +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf > > @@ -4,6 +4,8 @@ > > # It provides an implementation of DXE Core that is compliant with DX= E > CIS. > > # > > # Copyright (c) 2006 - 2017, Intel Corporation. All rights > > reserved.
> > +# Copyright (c) 2017, AMD Incorporated. All rights reserved.
# > > # This program and the accompanying materials # are licensed and > > made available under the terms and conditions of the BSD License # > > which accompanies this distribution. The full text of the license may > > be found at @@ > > -51,6 +53,8 @@ > > Hand/Handle.h > > Gcd/Gcd.c > > Gcd/Gcd.h > > + Gcd/GcdHelperCommon.c > > + Gcd/GcdHelper.h > > Mem/Pool.c > > Mem/Page.c > > Mem/MemData.c > > @@ -73,6 +77,12 @@ > > DxeMain/DxeProtocolNotify.c > > DxeMain/DxeMain.c > > > > +[Sources.Ia32] > > + Gcd/Ia32/GcdHelper.c > > + > > +[Sources.X64] > > + Gcd/X64/GcdHelper.c > > + > > [Packages] > > MdePkg/MdePkg.dec > > MdeModulePkg/MdeModulePkg.dec > > @@ -192,6 +202,7 @@ > > gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable > > ## CONSUMES > > gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy > > ## CONSUMES > > gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy > > ## CONSUMES > > + > > > gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrM > ask > > ## CONSUMES > > > > # [Hob] > > # RESOURCE_DESCRIPTOR ## CONSUMES > > diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c > > b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index a06f8bb..6f85c21 100644 > > --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c > > +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c > > @@ -4,6 +4,8 @@ > > are accessible to the CPU that is executing the DXE core. > > > > Copyright (c) 2006 - 2017, Intel Corporation. All rights > > reserved.
> > +Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > + > > This program and the accompanying materials are licensed and made > > available under the terms and conditions of the BSD License which > > accompanies this distribution. The full text of the license may be > > found at @@ -16,6 +18,7 @@ WITHOUT WARRANTIES OR > REPRESENTATIONS OF > > ANY KIND, EITHER EXPRESS OR IMPLIED. > > > > #include "DxeMain.h" > > #include "Gcd.h" > > +#include "GcdHelper.h" > > > > #define MINIMUM_INITIAL_MEMORY_SIZE 0x10000 > > > > @@ -723,6 +726,7 @@ CoreConvertSpace ( > > LIST_ENTRY *StartLink; > > LIST_ENTRY *EndLink; > > UINT64 CpuArchAttributes; > > + UINT64 AddressEncMask; > > > > if (Length =3D=3D 0) { > > DEBUG ((DEBUG_GCD, " Status =3D %r\n", EFI_INVALID_PARAMETER)); > @@ > > -741,6 +745,11 @@ CoreConvertSpace ( > > } > > > > // > > + // Make sure AddressEncMask is contained to smallest supported > > + address > > field. > > + // > > + AddressEncMask =3D PcdGet64 > (PcdPteMemoryEncryptionAddressOrMask) & > > + PAGING_1G_ADDRESS_MASK_64; > > + > > + // > > // Search for the list of descriptors that cover the range > > BaseAddress to > > BaseAddress+Length > > // > > Status =3D CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, > > &EndLink, Map); @@ -893,6 +902,11 @@ CoreConvertSpace ( > > Entry->GcdMemoryType =3D GcdMemoryType; > > if (GcdMemoryType =3D=3D EfiGcdMemoryTypeMemoryMappedIo) { > > Entry->Capabilities =3D Capabilities | EFI_MEMORY_RUNTIME | > > EFI_MEMORY_PORT_IO; > > + Status =3D ConvertEncryptionOnAddressRange (BaseAddress, > > + Length, > > CLEAR_ADDR_ENC_OPERATION, AddressEncMask); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((EFI_D_ERROR, "Could not CLEAR EncMask on Range: > > BaseAddress =3D 0xlX, Length =3D 0xlX, Status =3D %r\n", > > + BaseAddress, Length, Status)); > > + } > > } else { > > Entry->Capabilities =3D Capabilities | EFI_MEMORY_RUNTIME; > > } > > @@ -904,6 +918,13 @@ CoreConvertSpace ( > > // Free operations > > // > > case GCD_FREE_MEMORY_OPERATION: > > + if (Entry->Capabilities & EFI_MEMORY_PORT_IO) { > > + Status =3D ConvertEncryptionOnAddressRange (BaseAddress, > > + Length, > > SET_ADDR_ENC_OPERATION, AddressEncMask); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((EFI_D_ERROR, "Could not SET EncMask on Range: > > BaseAddress =3D 0xlX, Length =3D 0xlX, Status =3D %r\n", > > + BaseAddress, Length, Status)); > > + } > > + } > > case GCD_FREE_IO_OPERATION: > > Entry->ImageHandle =3D NULL; > > Entry->DeviceHandle =3D NULL; > > @@ -912,6 +933,13 @@ CoreConvertSpace ( > > // Remove operations > > // > > case GCD_REMOVE_MEMORY_OPERATION: > > + if (Entry->Capabilities & EFI_MEMORY_PORT_IO) { > > + Status =3D ConvertEncryptionOnAddressRange (BaseAddress, > > + Length, > > SET_ADDR_ENC_OPERATION, AddressEncMask); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((EFI_D_ERROR, "Could not SET EncMask on Range: > > BaseAddress =3D 0xlX, Length =3D 0xlX, Status =3D %r\n", > > + BaseAddress, Length, Status)); > > + } > > + } > > Entry->GcdMemoryType =3D EfiGcdMemoryTypeNonExistent; > > Entry->Capabilities =3D 0; > > break; > > diff --git a/MdeModulePkg/Core/Dxe/Gcd/GcdHelper.h > > b/MdeModulePkg/Core/Dxe/Gcd/GcdHelper.h > > new file mode 100644 > > index 0000000..d6ec339 > > --- /dev/null > > +++ b/MdeModulePkg/Core/Dxe/Gcd/GcdHelper.h > > @@ -0,0 +1,151 @@ > > +/** @file > > + Definitions for helper functions used by GCD. > > + > > +Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > + > > +This program and the accompanying materials are licensed and made > > +available 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 > > + > > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS > > OR IMPLIED. > > + > > +**/ > > + > > +#ifndef _GCD_HELPER_H_ > > +#define _GCD_HELPER_H_ > > + > > + > > +#pragma pack(1) > > +// > > +// Page Table Entry 4KB > > +// > > +typedef union { > > + struct { > > + UINT64 Present:1; // 0 =3D Not present in memory, = 1 =3D > > Present in memory > > + UINT64 ReadWrite:1; // 0 =3D Read-Only, 1=3D Read/Wr= ite > > + UINT64 UserSupervisor:1; // 0 =3D Supervisor, 1=3DUser > > + UINT64 WriteThrough:1; // 0 =3D Write-Back caching, > > 1=3DWrite-Through caching > > + UINT64 CacheDisabled:1; // 0 =3D Cached, 1=3DNon-Cached > > + UINT64 Accessed:1; // 0 =3D Not accessed, 1 =3D Acc= essed > > (set by CPU) > > + UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D writte= n by > > processor on access to page > > + UINT64 PAT:1; // > > + UINT64 Global:1; // 0 =3D Not global page, 1 =3D = global > > page TLB not cleared on CR3 write > > + UINT64 Available:3; // Available for use by system > > software > > + UINT64 PageTableBaseAddress:40; // Page Table Base Address > > + UINT64 AvailableHigh:11; // Available for use by system > > software > > + UINT64 Nx:1; // 0 =3D Execute Code, 1 =3D No = Code > > Execution > > + } Bits; > > + UINT64 Uint64; > > +} PAGE_TABLE_4K_ENTRY; > > + > > +// > > +// Page Table Entry 2MB > > +// > > +typedef union { > > + struct { > > + UINT64 Present:1; // 0 =3D Not present in memory, = 1 =3D > > Present in memory > > + UINT64 ReadWrite:1; // 0 =3D Read-Only, 1=3D Read/Wr= ite > > + UINT64 UserSupervisor:1; // 0 =3D Supervisor, 1=3DUser > > + UINT64 WriteThrough:1; // 0 =3D Write-Back caching, > > 1=3DWrite-Through caching > > + UINT64 CacheDisabled:1; // 0 =3D Cached, 1=3DNon-Cached > > + UINT64 Accessed:1; // 0 =3D Not accessed, 1 =3D Acc= essed > > (set by CPU) > > + UINT64 Dirty:1; // 0 =3D Not Dirty, 1 =3D writte= n by > > processor on access to page > > + UINT64 MustBe1:1; // Must be 1 > > + UINT64 Global:1; // 0 =3D Not global page, 1 =3D = global > > page TLB not cleared on CR3 write > > + UINT64 Available:3; // Available for use by system > > software > > + UINT64 PAT:1; // > > + UINT64 MustBeZero:8; // Must be zero; > > + UINT64 PageTableBaseAddress:31; // Page Table Base Address > > + UINT64 AvailableHigh:11; // Available for use by system > > software > > + UINT64 Nx:1; // 0 =3D Execute Code, 1 =3D No = Code > > Execution > > + } Bits; > > + UINT64 Uint64; > > +} PAGE_TABLE_2M_ENTRY; > > +#pragma pack() > > + > > + > > +typedef enum { > > + CLEAR_ADDR_ENC_OPERATION, > > + SET_ADDR_ENC_OPERATION, > > + INVALID_ENC_OPERATION > > +} ADDR_ENC_OPERATION; > > + > > + > > +#define IA32_PG_P BIT0 > > +#define IA32_PG_RW BIT1 > > +#define IA32_PG_PS BIT7 > > + > > +#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull > #define > > +PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull #define > > +PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull > > + > > + > > +/** > > + Convert Encryption on address range > > + > > + @param BaseAddress Start address of the range > > + @param Length Length of the segment > > + @param Operation Convertion operation (set or clear) > > + @param AddressEncMask Address Encryption Mask > > + > > + @retval EFI_INVALID_PARAMETER Length or Address not aligned on > > EFI_PAGE_SIZE boundary. > > + @retval EFI_NO_MAPPING Missing page table mappings for the > > specified segment. > > + @retval EFI_SUCCESS Action successfully done. > > +**/ > > +EFI_STATUS > > +ConvertEncryptionOnAddressRange ( > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN ADDR_ENC_OPERATION Operation, > > + IN UINT64 AddressEncMask > > + ); > > + > > +/** > > + Convert Encryption on page table entry. > > + > > + @param PageTableEntry Start address of the range > > + @param Operation Convertion operation (set or clear) > > + @param AddressEncMask Address Encryption Mask > > + > > +**/ > > +VOID > > +ConvertEncryptionOnPageTableEntry ( > > + IN UINT64 *PageTableEntry, > > + IN ADDR_ENC_OPERATION Operation, > > + IN UINT64 AddressEncMask > > + ); > > + > > +/** > > + Split 1G page to 2M on Encrypted address range. > > + > > + @param[in] PhysicalAddress Address of the encryted range. > > + @param[in] AddressEncMask Address Encryption Mask. > > + @param[in, out] PageEntry1G Pointer to 1G page entry. > > + > > +**/ > > +VOID > > +Split1GPageTo2MPageOnEncRange ( > > + IN EFI_PHYSICAL_ADDRESS PhysicalAddress, > > + IN UINT64 AddressEncMask, > > + IN OUT UINT64 *PageEntry1G > > + ); > > + > > +/** > > + Split 2M page to 4K on Encrypted address range. > > + > > + @param[in] PhysicalAddress Address of the range. > > + @param[in] AddressEncmask Encryption Mask. > > + @param[in, out] PageEntry2M Pointer to 2M page entry. > > + > > +**/ > > +VOID > > +Split2MPageTo4KPageOnEncRange ( > > + IN EFI_PHYSICAL_ADDRESS PhysicalAddress, > > + IN UINT64 AddressEncMask, > > + IN OUT UINT64 *PageEntry2M > > + ); > > + > > +#endif // _GCD_HELPER_H_ > > + > > diff --git a/MdeModulePkg/Core/Dxe/Gcd/GcdHelperCommon.c > > b/MdeModulePkg/Core/Dxe/Gcd/GcdHelperCommon.c > > new file mode 100644 > > index 0000000..1660732 > > --- /dev/null > > +++ b/MdeModulePkg/Core/Dxe/Gcd/GcdHelperCommon.c > > @@ -0,0 +1,120 @@ > > +/** @file > > + The file contains helper functions used by GCD. > > + > > +Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > + > > +This program and the accompanying materials are licensed and made > > +available 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 > > + > > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS > > OR IMPLIED. > > + > > +**/ > > + > > +#include "DxeMain.h" > > +#include "GcdHelper.h" > > + > > + > > +/** > > + Split 2M page to 4K on Encrypted address range. > > + > > + @param[in] PhysicalAddress Address of the range. > > + @param[in] AddressEncmask Encryption Mask. > > + @param[in, out] PageEntry2M Pointer to 2M page entry. > > + > > +**/ > > +VOID > > +Split2MPageTo4KPageOnEncRange ( > > + IN EFI_PHYSICAL_ADDRESS PhysicalAddress, > > + IN UINT64 AddressEncMask, > > + IN OUT UINT64 *PageEntry2M > > + ) > > +{ > > + EFI_PHYSICAL_ADDRESS PhysicalAddress4K; > > + UINTN IndexOfPageTableEntries; > > + PAGE_TABLE_4K_ENTRY *PageTableEntry; > > + > > + PageTableEntry =3D (PAGE_TABLE_4K_ENTRY *)AllocatePages (1); ASSERT > > + (PageTableEntry !=3D NULL); > > + > > + // > > + // Fill in 2M page entry. > > + // > > + *PageEntry2M =3D (UINT64)(UINTN) PageTableEntry | AddressEncMask | > > + IA32_PG_P | IA32_PG_RW; > > + > > + PhysicalAddress4K =3D PhysicalAddress; for (IndexOfPageTableEntries > > + =3D 0; IndexOfPageTableEntries < 512; > > IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K +=3D > > IndexOfPageTableEntries++SIZE_4KB) > > { > > + // > > + // Fill in the Page Table entries > > + // > > + PageTableEntry->Uint64 =3D (UINT64) PhysicalAddress4K | > AddressEncMask; > > + PageTableEntry->Bits.ReadWrite =3D 1; > > + PageTableEntry->Bits.Present =3D 1; > > + } > > +} > > + > > + > > +/** > > + Split 1G page to 2M on Encrypted address range. > > + > > + @param[in] PhysicalAddress Address of the encryted range. > > + @param[in] AddressEncMask Address Encryption Mask. > > + @param[in, out] PageEntry1G Pointer to 1G page entry. > > + > > +**/ > > +VOID > > +Split1GPageTo2MPageOnEncRange ( > > + IN EFI_PHYSICAL_ADDRESS PhysicalAddress, > > + IN UINT64 AddressEncMask, > > + IN OUT UINT64 *PageEntry1G > > + ) > > +{ > > + EFI_PHYSICAL_ADDRESS PhysicalAddress2M; > > + UINTN IndexOfPageDirectoryEntries; > > + PAGE_TABLE_2M_ENTRY *PageDirectoryEntry; > > + > > + PageDirectoryEntry =3D (PAGE_TABLE_2M_ENTRY *)AllocatePages (1); > > + ASSERT (PageDirectoryEntry !=3D NULL); > > + > > + // > > + // Fill in 1G page entry. > > + // > > + *PageEntry1G =3D (UINT64)(UINTN) PageDirectoryEntry | AddressEncMask > > + | IA32_PG_P | IA32_PG_RW; > > + > > + PhysicalAddress2M =3D PhysicalAddress; for > > + (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEntries < 512= ; > > IndexOfPageDirectoryEntries++, PageDirectoryEntry++, > PhysicalAddress2M > > IndexOfPageDirectoryEntries+++=3D > > SIZE_2MB) { > > + // > > + // Fill in the Page Directory entries > > + // > > + PageDirectoryEntry->Uint64 =3D (UINT64) PhysicalAddress2M | > > AddressEncMask; > > + PageDirectoryEntry->Bits.ReadWrite =3D 1; > > + PageDirectoryEntry->Bits.Present =3D 1; > > + PageDirectoryEntry->Bits.MustBe1 =3D 1; > > + } > > +} > > + > > + > > +/** > > + Convert Encryption on page table entry. > > + > > + @param PageTableEntry Start address of the range > > + @param Operation Convertion operation (set or clear) > > + @param AddressEncMask Address Encryption Mask > > + > > +**/ > > +VOID > > +ConvertEncryptionOnPageTableEntry ( > > + IN UINT64 *PageTableEntry, > > + IN ADDR_ENC_OPERATION Operation, > > + IN UINT64 AddressEncMask > > + ) > > +{ > > + if (Operation =3D=3D CLEAR_ADDR_ENC_OPERATION) { > > + *PageTableEntry &=3D ~AddressEncMask; > > + } else if (Operation =3D=3D SET_ADDR_ENC_OPERATION) { > > + *PageTableEntry |=3D AddressEncMask; > > + } > > +} > > + > > diff --git a/MdeModulePkg/Core/Dxe/Gcd/Ia32/GcdHelper.c > > b/MdeModulePkg/Core/Dxe/Gcd/Ia32/GcdHelper.c > > new file mode 100644 > > index 0000000..4781900 > > --- /dev/null > > +++ b/MdeModulePkg/Core/Dxe/Gcd/Ia32/GcdHelper.c > > @@ -0,0 +1,115 @@ > > +/** @file > > + The file contains helper functions used by GCD. > > + > > +Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > + > > +This program and the accompanying materials are licensed and made > > +available 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 > > + > > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS > > OR IMPLIED. > > + > > +**/ > > + > > +#include "DxeMain.h" > > +#include "GcdHelper.h" > > + > > + > > +/** > > + Convert Encryption on address range. > > + > > + @param BaseAddress Start address of the range > > + @param Length Length of the range > > + @param Operation Convertion operation (set or clear) > > + @param AddressEncMask Address Encryption Mask > > + > > + @retval EFI_INVALID_PARAMETER Length or Address not aligned on > > EFI_PAGE_SIZE boundary. > > + @retval EFI_NO_MAPPING Missing page table mappings for the > > specified range. > > + @retval EFI_SUCCESS Action successfully done. > > +**/ > > +EFI_STATUS > > +ConvertEncryptionOnAddressRange ( > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN ADDR_ENC_OPERATION Operation, > > + IN UINT64 AddressEncMask > > + ) > > +{ > > + EFI_PHYSICAL_ADDRESS PhysicalAddress; > > + UINT64 *PageTable; > > + UINTN PTIndex; > > + UINT64 Cr3; > > + > > + // Do we have actual work to do? > > + if (Length =3D=3D 0 || AddressEncMask =3D=3D 0) { > > + return EFI_SUCCESS; > > + } > > + > > + // PAE *must* be enabled on 32-bit page tables // (else we can't > > + configure AddressEncMask) if ((AsmReadCr4 () & BIT5) =3D=3D 0) { > > + return EFI_SUCCESS; > > + } > > + > > + // Make sure we're PAGE_SIZE aligned if ((BaseAddress & > > + EFI_PAGE_MASK) || (Length & EFI_PAGE_MASK)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // Validate Operation > > + if (Operation >=3D INVALID_ENC_OPERATION) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Cr3 =3D AsmReadCr3 (); > > + PhysicalAddress =3D BaseAddress; > > + > > + do { > > + // PDPE Present? > > + PageTable =3D (UINT64 *)(UINTN) (Cr3 & ~AddressEncMask & > > PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 30, 31); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // PDE Present? > > + PageTable =3D (UINT64 *)(UINTN) (PageTable[PTIndex] & > > + ~AddressEncMask > > & PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 21, 29); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // Is it a 2MB page entry? > > + if ((PageTable[PTIndex] & IA32_PG_PS ) !=3D 0) { > > + if ((PhysicalAddress & (SIZE_2MB - 1)) =3D=3D 0 && Length >=3D S= IZE_2MB) { > > + // Consume 2MB from the range > > + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], > > Operation, AddressEncMask); > > + PhysicalAddress +=3D SIZE_2MB; > > + Length -=3D SIZE_2MB; > > + } else { > > + // Split 2MB page entry to consume 4K chunks > > + Split2MPageTo4KPageOnEncRange (PhysicalAddress, > > + AddressEncMask, > > &PageTable[PTIndex]); > > + } > > + } else { > > + // PTE Present? > > + PageTable =3D (UINT64 *)(UINTN) (PageTable[PTIndex] & > > ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 12, 20); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // Consume 4KB from the range > > + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], > > + Operation, > > AddressEncMask); > > + PhysicalAddress +=3D SIZE_4KB; > > + Length -=3D SIZE_4KB; > > + } > > + } while (Length); > > + > > + // Flush TLB > > + AsmWriteCr3 (Cr3); > > + > > + return EFI_SUCCESS; > > +} > > + > > diff --git a/MdeModulePkg/Core/Dxe/Gcd/X64/GcdHelper.c > > b/MdeModulePkg/Core/Dxe/Gcd/X64/GcdHelper.c > > new file mode 100644 > > index 0000000..5943f7a > > --- /dev/null > > +++ b/MdeModulePkg/Core/Dxe/Gcd/X64/GcdHelper.c > > @@ -0,0 +1,129 @@ > > +/** @file > > + The file contains helper functions used by GCD. > > + > > +Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > + > > +This program and the accompanying materials are licensed and made > > +available 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 > > + > > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS > > OR IMPLIED. > > + > > +**/ > > + > > +#include "DxeMain.h" > > +#include "GcdHelper.h" > > + > > + > > +/** > > + Convert Encryption on address range. > > + > > + @param BaseAddress Start address of the range > > + @param Length Length of the range > > + @param Operation Convertion operation (set or clear) > > + @param AddressEncMask Address Encryption Mask > > + > > + @retval EFI_INVALID_PARAMETER Length or Address not aligned on > > EFI_PAGE_SIZE boundary. > > + @retval EFI_NO_MAPPING Missing page table mappings for the > > specified range. > > + @retval EFI_SUCCESS Action successfully done. > > +**/ > > +EFI_STATUS > > +ConvertEncryptionOnAddressRange ( > > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > > + IN UINT64 Length, > > + IN ADDR_ENC_OPERATION Operation, > > + IN UINT64 AddressEncMask > > + ) > > +{ > > + EFI_PHYSICAL_ADDRESS PhysicalAddress; > > + UINT64 *PageTable; > > + UINTN PTIndex; > > + UINT64 Cr3; > > + > > + // Do we have actual work to do? > > + if (Length =3D=3D 0 || AddressEncMask =3D=3D 0) { > > + return EFI_SUCCESS; > > + } > > + > > + // Make sure we're PAGE_SIZE aligned if ((BaseAddress & > > + EFI_PAGE_MASK) || (Length & EFI_PAGE_MASK)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // Validate Operation > > + if (Operation >=3D INVALID_ENC_OPERATION) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Cr3 =3D AsmReadCr3 (); > > + PhysicalAddress =3D BaseAddress; > > + > > + do { > > + // PML4E Present? > > + PageTable =3D (UINT64 *)(UINTN) (Cr3 & ~AddressEncMask & > > PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 39, 47); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // PDPE Present? > > + PageTable =3D (UINT64 *)(UINTN) (PageTable[PTIndex] & > > + ~AddressEncMask > > & PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 30, 38); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // Is it a 1GB page entry? > > + if ((PageTable[PTIndex] & IA32_PG_PS ) !=3D 0) { > > + if ((PhysicalAddress & (SIZE_1GB - 1)) =3D=3D 0 && Length >=3D S= IZE_1GB) { > > + // Consume 1GB from the range > > + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], > > Operation, AddressEncMask); > > + PhysicalAddress +=3D SIZE_1GB; > > + Length -=3D SIZE_1GB; > > + } else { > > + // Split 1G page entry to attempt consuming 2MB chunks > > + Split1GPageTo2MPageOnEncRange (PhysicalAddress, > > + AddressEncMask, > > &PageTable[PTIndex]); > > + } > > + } else { > > + // PDE Present? > > + PageTable =3D (UINT64 *)(UINTN) (PageTable[PTIndex] & > > ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 21, 29); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // Is it a 2MB page entry? > > + if ((PageTable[PTIndex] & IA32_PG_PS ) !=3D 0) { > > + if ((PhysicalAddress & (SIZE_2MB - 1)) =3D=3D 0 && Length >=3D= SIZE_2MB) { > > + // Consume 2MB from the range > > + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], > > Operation, AddressEncMask); > > + PhysicalAddress +=3D SIZE_2MB; > > + Length -=3D SIZE_2MB; > > + } else { > > + // Split 2MB page entry to consume 4K chunks > > + Split2MPageTo4KPageOnEncRange (PhysicalAddress, > > AddressEncMask, &PageTable[PTIndex]); > > + } > > + } else { > > + // PTE Present? > > + PageTable =3D (UINT64 *)(UINTN) (PageTable[PTIndex] & > > ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + PTIndex =3D BitFieldRead64(PhysicalAddress, 12, 20); > > + if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > + return EFI_NO_MAPPING; > > + } > > + > > + // Consume 4KB from the range > > + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], > > Operation, AddressEncMask); > > + PhysicalAddress +=3D SIZE_4KB; > > + Length -=3D SIZE_4KB; > > + } > > + } > > + } while (Length); > > + > > + // Flush TLB > > + AsmWriteCr3 (Cr3); > > + > > + return EFI_SUCCESS; > > +} > > + > > -- > > 2.7.4 > > > > _______________________________________________ > > edk2-devel mailing list > > edk2-devel@lists.01.org > > https://lists.01.org/mailman/listinfo/edk2-devel