From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM03-BY2-obe.outbound.protection.outlook.com (mail-by2nam03on062f.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe4a::62f]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 4E037803A1 for ; Thu, 23 Mar 2017 19:51:42 -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=osKiu/iDVF50f3P4kDlU16QH7xNdvgPk4uo2eay40Hc=; b=MugmsVBmimNGtu62i/EmQgl61jX06VXuXf/84lnWetYt/Vte0bhdeb5QKaaLWbA53DxPczprrSFD3cPYYuUnCA85zk/zgxXejDTguncyppNyTWYpHXsIqpDcofT2GHISulkj2BgvGviHp3/8oms3vIjn9gcoM23tAdU65MTbOQU= Authentication-Results: ml01.01.org; dkim=none (message not signed) header.d=none;ml01.01.org; dmarc=none action=none header.from=amd.com; Received: from leduran-Precision-WorkStation-T5400.amd.com (165.204.77.1) by DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) 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 02:51:40 +0000 From: Leo Duran To: CC: Leo Duran , Feng Tian , Star Zeng , Brijesh Singh Date: Thu, 23 Mar 2017 21:51:27 -0500 Message-ID: <1490323887-9686-2-git-send-email-leo.duran@amd.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490323887-9686-1-git-send-email-leo.duran@amd.com> References: <1490323887-9686-1-git-send-email-leo.duran@amd.com> MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SN1PR19CA0007.namprd19.prod.outlook.com (10.163.220.17) To DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) X-MS-Office365-Filtering-Correlation-Id: 76496e78-b9e2-4995-f071-08d47260b2fa X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:DM5PR12MB1243; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 3:eznpYORzx1G2U+3AeoxyXfb/kgjgzMXt5rejfAU8JzyEL1DlKAfWfzuDS8tH7fg70g2TH3o2WRv65qr3mtybvNPei15yerjI3WBjXkcrch/VtucGUEjrYCPL8nt+GwKDXb2Q4vhzbC6pRG6h75n4kliUKuDcAIhIO/AJGVIFbQqKwLOgOyOgVu8JRqTdKYtJ0Qc/5eoWzit9aegj1Q8qJdlYR9LZcXE4f0kv8mT1KO14rEnPhIeEJSJy9VGBsPlHUeibWJ2IiMbIXfpmo3+hnqzvLKucCdsscMCVmxk6eV0=; 25:JmdRAlgQfEq/P10nhQIw6+VH6UtODbrigQrMiKHVU5dU1He8JkNLaLXHK+msq10027OCBvmWpFXIspDzq1Sl5572sTBfpZbB63YuXDI2KA2M7QX8Kng2VVsFxrSYSWB12FY+PnCgHfj7u/Ud/GOpEc+ubqmqS4U4H/CDLjv0G1OccKqQhgH5fgXND+abEofpw+hrwzynjLPQqr4g113GrCnAXA/HsTe3pO+qe8V1nkYFWG7kxq5lun4bXJBhocVsM67ybl3eXkAoyYLHMyt1PQ195Se37XAM2If+NgHBAQlJ6kt3NveOpUEks0Z4dhNvF9pXS6f7PK3tqDL95R5O0ucxwp1ArnJdICOHnQ5UsowrcuXhPXz1WzCmGNe3KJwPoqupFu56Pqgv5cLBtf3IsaExLOjSJaC9LnSnRYtRh2dABN2QWZXZ+4AOi8lDhoiQJQE43bbZqOx5bnT9Jjt1gg== X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 31:FCyKqu+LYhjiI6tFJfRn5YjK8KtIMKJ2LIpqLFJPgYx2UdtLoQI0tuUfQivktGQTXiaGKm5kBbuEmun2NhhvhQ02u1OjmKOtUhhx/0gn7WR+QTpqNxiGHdK22+zla8ZDj3AYnqK5ZRl52fVhiMaxAVKs1pxwQ2cvrSxo3u5mYtO55YOEz2l7nYZpdLw8Et59EEf1x+l9osN0pW36itX41bh7e//ZGZt9Dps0GyeyFNulv+9NkX1RZPr1V856ZsuW; 20:v8P2bXy1v67UnokcuCAsRuZjqt/7937YPJEggB2WuhsxASAelWZbWVDiFSk8Y2kWT7+A7/mQIA8jcNeQoaKEolNDhlP7pEsOuKhwzBp209UQRWxVL/9KSJarIyUkmjHggNWYwcEctvtQm82xA7Hips/j2Eews7IN6eK0R8SbzV3jnKbqsgo0v9GluHbc65gM3+Gnj/XxG+SNSqWx4PcNeUP+KHN9OSZbKv8R2WYYGaZ8C3oLPDVgUSFwz6Oal+1Qq805UhrXp67OcEkazASrMzLGVanxgipOaDySGNUrNjXATJp+fZ2bjmliXIAqJ7EQyvzq5Eqqv10kMeesRItEWlPn5D+b17uYokzBS3j5qMPOjPU/ZVHpymfh4LMjUCJQTAlLnItV63gBRhedJh4Aei6fuiQpbLqHo64k++BYmQg2iZR+R3QkC8TmpaeL/eBH444enhv0uHjC5rFFVOUKrCf35DyqeMkF+m16GFAq+HpJ+q8XyHMWIt95lJmhif40 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110)(228905959029699); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026)(6041248)(20161123560025)(20161123564025)(20161123562025)(20161123558025)(20161123555025)(6072148); SRVR:DM5PR12MB1243; BCL:0; PCL:0; RULEID:; SRVR:DM5PR12MB1243; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 4:X2DwgAPZmHynLeFJpJXXTvkCBuMSaSxLFaUjKjoVH6FW6Piw6fhu5Bfz/GahtV/Iwgf3+wt5FV7A0GXIAJrUWg7vR260rTb5zH+C8Uq200rupDPukpNzN0qIDasdIkQlXo+jdi9Y8QehFY45rPuUIPICMyXYYfJ1DXYHGsxPdMQO1jtNL9Mr+LJgvelRKsr0KRvEX+ZxLWMu7NaSaxAa9jqyQ6Erc26HEDmCZOHgWyGYS594qzBG6A8+ZS5iYPpZPUvvW1Ya9j/frNyTc7iizSqhjT53Z8m7Ka2E5Gg8AiF+1WKf0WZsMK7UajR1B9yDwEQkGZS7dBnWEB8BLFmKcxsRMxEIMphzt3gfQsc9/ld9sjxfv1QQbTqtsEKzOs1O3ThZfH0YN2H+M5Mw3wRDBt2N8szo7fzfereurWKgldHj4w9kTYS3CKaOFEEkebd0NFp29mq0JqnanOURChmrF4ckweTB8s3cUeVxvf0tDQmJcN8RFVDSwzQhG2QV7r2PeghCLbo44U2ahr+1sKcE4LL74995X/a0RVPOrPumy0SkAY3SSf4Tz0P9ZtFJS0eRjztDB6vYCKnZTaf3syfd40gHgY6eSb9bX1xleiFM1ebtUxL0ZXrr+NxKhtsnnfm1rBl4/tsco42oZv2rQLZFw2ftj8MUPO1dZe+/6j0Y3WogmSaBUAyjPX8ajQCSVb33 X-Forefront-PRVS: 0256C18696 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(39850400002)(39840400002)(39860400002)(39450400003)(39410400002)(189998001)(5003940100001)(16799955002)(81166006)(2906002)(53416004)(15188155005)(50466002)(305945005)(86362001)(6916009)(2950100002)(38730400002)(110136004)(8676002)(53376002)(6666003)(36756003)(4326008)(42186005)(6486002)(47776003)(33646002)(6116002)(25786009)(54906002)(2351001)(3846002)(7736002)(76176999)(50986999)(50226002)(48376002)(6306002)(53936002)(5660300001)(66066001)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR12MB1243; H:leduran-Precision-WorkStation-T5400.amd.com; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM5PR12MB1243; 23:ACoY2pFCVtYvYw7m6eLhNWa4Ih0owfgiJrP9uZnX7?= =?us-ascii?Q?hEp/GJcovD3CDlnjWMS447wEWSi+omqGmZgnQTzpJJLD9eHV0WLZEC/L1YIm?= =?us-ascii?Q?hXUKprzx0ZUF+SUVdJA60xZquAd9JpKmB+BZ7QLsfRHLJ1mpPHwD1/ghvB5s?= =?us-ascii?Q?xL5S7xndanFmxZE6RzxdKdXoejAABBpkaa3dMOVnMUiOzRVEQxwu4oOXv8iR?= =?us-ascii?Q?1r5VG+aQ89Q+PihCvqLPhj4ikzPrmDh/ChGtLfhMlDZ2IgLGRGQmBeEdhldd?= =?us-ascii?Q?IZhs2iQGlOAVt/p4btXYdYhhCsU0EcEUBsk8LScm2U2Cf6xrs+QDqgaL0AHM?= =?us-ascii?Q?KxL8KuxPVqRFL2A1xf0nZP0y6dQzd5Ofa03dwivW4IIu9CjglLijkNokArE9?= =?us-ascii?Q?/O/YXS7f/sh/NZehCBdRFTBhgeewdnhysSeH9TRWUJ4lE6QGp+LSLIuHrn8N?= =?us-ascii?Q?SNw/xyXmXnAomhhi1CdmZomQN9l6ULl0zyc4iUTjQ+kwR9I3g96XxTBpImgE?= =?us-ascii?Q?8zVc8a9YyXd3teIu4RUJyaMMHhk6R1rX8V+KZzty8kSzUvlax+6+PY7bnlUE?= =?us-ascii?Q?H75ZAZm1hmNv+6lOkNaqR6Z21noYbIhz6KCQo9SZp5PhOgpHh4iLCYFnpN+a?= =?us-ascii?Q?vh1wabFA8DZwxKndmSzHgnKFZ8WYsUoeRQVb5J55zO2cJqx8x9Nwz7AiEm+J?= =?us-ascii?Q?WJxhI5psXIodVmFT5RMo8GGO9eGc0RfoFCFzkenfhDfZlfHaZ3labaiUjH+u?= =?us-ascii?Q?ht6O115gOuLF1VEHjgekaEEuLfQp3A37qy/kfEeAZrbsl8LdnzfcqoQCBXwC?= =?us-ascii?Q?OiVye1A/Oe9FA7YDK1lapQ0Vhk0fZhtQTOSgN1K8c9gnfJ3wfi+SRHHbK5N5?= =?us-ascii?Q?OgXAtnMaoTkWkWMlCCLOACbh5IX5nVU9Q2ddYMXOXMfO/5CdsFtdjQpfRHhj?= =?us-ascii?Q?0Xaea62ZiYdf+fj2zqqbKESLf26mktoG2Z3H+hJx3UlteNbD3nekWrMsGp9H?= =?us-ascii?Q?vXWwKVLn971DNDMcw/WOeSkIt6fAw3v5FyKSfNU2HQspfEK0ARJOKOdXB1bG?= =?us-ascii?Q?v2EtDy1923FvNpGXlgYyNtws2tZOou8U+/Lrb/ZlHdgoiyiM8eCtkWh8OWng?= =?us-ascii?Q?zIbWHqiNpgNAlNOEriOJCEm4bTLEySR?= X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 6:AW8v30saglbZpi51erUdzkCoA03a4YZf6HIIeUeYBnHI9sdBEez4JYSZDrOxEu5dSVIUPqyAPb9W4WdLJcv/nfcXxwUea/YywcUz9GrZ+yoRuHbwRTDV1P/EGTA+vgsiGWqnJwOXijX0SIQvuBMaNJBEZ/mrI+n2Vd97tTWjU9HaECvpLXkq/yERUXFEHRMRDsXtoCoSgLeDtHFA9ebDNdC983dssx4l0biJH0G87zYiqweDRn19U7VMtg5JcQ4c+gJiVsOTz53Vc8CLCda84iPwWfUk7aPeXT+lj6czjIU2byWe3QBcFG6Cq4l2a2+rYiMuzHir8qCBE5OMI9e8PGrlFgAAzZgMdECzDzJt9eCpf1R6Swp/2tujVc9rWtUQtN5CK9ob7d+AKawBQFRJEfZG4HRCZ6RvII0winBWhNU=; 5:EONK1iBCBNbh0tiLBscJGz8sGWD4F4xdP/WFozhxvDJEmPAZxBzVrIJrPeJu+YhyIleEepqC6x5Q3FqJ0YQBYke5Pwq4mqt3Ifpi84UT1y1MR0PsTcMS+cxO3LXuFUA9uedAtnr4xGCVJ0VblLAldw==; 24:oA4YuATbleNJ6XWue8fgVLd61EUaM0pNAEBHxov851ZYWyhyvNaFyQ3/k8uxsak/N9ahxD7Xkx6hmQ3KCrNQrBec/1MajTulN4JSAu759T0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1243; 7:r7XmVsZ2iVFjZ6jZo8oHQHHhMg5m184fp/1+yvxxuGq+yxdDdsCW67ncKsgClaIXhStOU6sralL+AT3RnsXTB0cNZ+dPx49UniGQlrRH9KtJfimOC18JhRmLGrSwEeQLmkwRw59DNReHVfOOfXZ2pHlCYQb3sIOIf5X7PS6ooQPPYZS68yrSp3lZUxgTqHI0vhoAYb+q3+g63HEWTkzpxwJqxRIaeoOOa8o3PAAoWLNLAoFLXBThrqTpye15AKz0j/XuWubufPlb0QAotvDRdxfyVQwigOV/0kV2K4D1VKpTMpEvOy6bCYxGnKqmj7UONK2t6vuTs2Iht1wTfSAEIQ==; 20:ZtDURDVvJ+Ue7SsX4ELE6EiJzWjIk8bHAI8tBRaRhwhAX9Yr0/Pp11t3asWwawle9IxFAlqRNDHvoAZlKTFe7tnR2taf7POlO/7zxZESn9RcKbHcY5kOf8pD+LXYxgxnFcw+PMjBmrkc0gBRI5blGYebv4crFWP2g0oAVERsgNjNbin2i0R9/xiWBOL6Wl0sS7QR9dFdSgid1zXJAtLkbTcSyozThc9ZYbJY8izeN73iAXW7lfhGhND4FYRrvxus X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Mar 2017 02:51:40.8507 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1243 Subject: [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 02:51:42 -0000 Content-Type: text/plain 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 DXE 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.PcdPteMemoryEncryptionAddressOrMask ## 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 == 0) { DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); @@ -741,6 +745,11 @@ CoreConvertSpace ( } // + // Make sure AddressEncMask is contained to smallest supported address field. + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + // // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length // Status = CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, &EndLink, Map); @@ -893,6 +902,11 @@ CoreConvertSpace ( Entry->GcdMemoryType = GcdMemoryType; if (GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME | EFI_MEMORY_PORT_IO; + Status = ConvertEncryptionOnAddressRange (BaseAddress, Length, CLEAR_ADDR_ENC_OPERATION, AddressEncMask); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Could not CLEAR EncMask on Range: BaseAddress = 0xlX, Length = 0xlX, Status = %r\n", + BaseAddress, Length, Status)); + } } else { Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME; } @@ -904,6 +918,13 @@ CoreConvertSpace ( // Free operations // case GCD_FREE_MEMORY_OPERATION: + if (Entry->Capabilities & EFI_MEMORY_PORT_IO) { + Status = ConvertEncryptionOnAddressRange (BaseAddress, Length, SET_ADDR_ENC_OPERATION, AddressEncMask); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Could not SET EncMask on Range: BaseAddress = 0xlX, Length = 0xlX, Status = %r\n", + BaseAddress, Length, Status)); + } + } case GCD_FREE_IO_OPERATION: Entry->ImageHandle = NULL; Entry->DeviceHandle = NULL; @@ -912,6 +933,13 @@ CoreConvertSpace ( // Remove operations // case GCD_REMOVE_MEMORY_OPERATION: + if (Entry->Capabilities & EFI_MEMORY_PORT_IO) { + Status = ConvertEncryptionOnAddressRange (BaseAddress, Length, SET_ADDR_ENC_OPERATION, AddressEncMask); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Could not SET EncMask on Range: BaseAddress = 0xlX, Length = 0xlX, Status = %r\n", + BaseAddress, Length, Status)); + } + } Entry->GcdMemoryType = EfiGcdMemoryTypeNonExistent; Entry->Capabilities = 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 = Not present in memory, 1 = Present in memory + UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write + UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User + UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching + UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached + UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) + UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page + UINT64 PAT:1; // + UINT64 Global:1; // 0 = Not global page, 1 = 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 = Execute Code, 1 = No Code Execution + } Bits; + UINT64 Uint64; +} PAGE_TABLE_4K_ENTRY; + +// +// Page Table Entry 2MB +// +typedef union { + struct { + UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory + UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write + UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User + UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching + UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached + UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) + UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page + UINT64 MustBe1:1; // Must be 1 + UINT64 Global:1; // 0 = Not global page, 1 = 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 = Execute Code, 1 = 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 = (PAGE_TABLE_4K_ENTRY *)AllocatePages (1); + ASSERT (PageTableEntry != NULL); + + // + // Fill in 2M page entry. + // + *PageEntry2M = (UINT64)(UINTN) PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; + + PhysicalAddress4K = PhysicalAddress; + for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) { + // + // Fill in the Page Table entries + // + PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask; + PageTableEntry->Bits.ReadWrite = 1; + PageTableEntry->Bits.Present = 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 = (PAGE_TABLE_2M_ENTRY *)AllocatePages (1); + ASSERT (PageDirectoryEntry != NULL); + + // + // Fill in 1G page entry. + // + *PageEntry1G = (UINT64)(UINTN) PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; + + PhysicalAddress2M = PhysicalAddress; + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) { + // + // Fill in the Page Directory entries + // + PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | AddressEncMask; + PageDirectoryEntry->Bits.ReadWrite = 1; + PageDirectoryEntry->Bits.Present = 1; + PageDirectoryEntry->Bits.MustBe1 = 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 == CLEAR_ADDR_ENC_OPERATION) { + *PageTableEntry &= ~AddressEncMask; + } else if (Operation == SET_ADDR_ENC_OPERATION) { + *PageTableEntry |= 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 == 0 || AddressEncMask == 0) { + return EFI_SUCCESS; + } + + // PAE *must* be enabled on 32-bit page tables + // (else we can't configure AddressEncMask) + if ((AsmReadCr4 () & BIT5) == 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 >= INVALID_ENC_OPERATION) { + return EFI_INVALID_PARAMETER; + } + + Cr3 = AsmReadCr3 (); + PhysicalAddress = BaseAddress; + + do { + // PDPE Present? + PageTable = (UINT64 *)(UINTN) (Cr3 & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 30, 31); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // PDE Present? + PageTable = (UINT64 *)(UINTN) (PageTable[PTIndex] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 21, 29); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // Is it a 2MB page entry? + if ((PageTable[PTIndex] & IA32_PG_PS ) != 0) { + if ((PhysicalAddress & (SIZE_2MB - 1)) == 0 && Length >= SIZE_2MB) { + // Consume 2MB from the range + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], Operation, AddressEncMask); + PhysicalAddress += SIZE_2MB; + Length -= SIZE_2MB; + } else { + // Split 2MB page entry to consume 4K chunks + Split2MPageTo4KPageOnEncRange (PhysicalAddress, AddressEncMask, &PageTable[PTIndex]); + } + } else { + // PTE Present? + PageTable = (UINT64 *)(UINTN) (PageTable[PTIndex] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 12, 20); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // Consume 4KB from the range + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], Operation, AddressEncMask); + PhysicalAddress += SIZE_4KB; + Length -= 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 == 0 || AddressEncMask == 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 >= INVALID_ENC_OPERATION) { + return EFI_INVALID_PARAMETER; + } + + Cr3 = AsmReadCr3 (); + PhysicalAddress = BaseAddress; + + do { + // PML4E Present? + PageTable = (UINT64 *)(UINTN) (Cr3 & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 39, 47); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // PDPE Present? + PageTable = (UINT64 *)(UINTN) (PageTable[PTIndex] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 30, 38); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // Is it a 1GB page entry? + if ((PageTable[PTIndex] & IA32_PG_PS ) != 0) { + if ((PhysicalAddress & (SIZE_1GB - 1)) == 0 && Length >= SIZE_1GB) { + // Consume 1GB from the range + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], Operation, AddressEncMask); + PhysicalAddress += SIZE_1GB; + Length -= SIZE_1GB; + } else { + // Split 1G page entry to attempt consuming 2MB chunks + Split1GPageTo2MPageOnEncRange (PhysicalAddress, AddressEncMask, &PageTable[PTIndex]); + } + } else { + // PDE Present? + PageTable = (UINT64 *)(UINTN) (PageTable[PTIndex] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 21, 29); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // Is it a 2MB page entry? + if ((PageTable[PTIndex] & IA32_PG_PS ) != 0) { + if ((PhysicalAddress & (SIZE_2MB - 1)) == 0 && Length >= SIZE_2MB) { + // Consume 2MB from the range + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], Operation, AddressEncMask); + PhysicalAddress += SIZE_2MB; + Length -= SIZE_2MB; + } else { + // Split 2MB page entry to consume 4K chunks + Split2MPageTo4KPageOnEncRange (PhysicalAddress, AddressEncMask, &PageTable[PTIndex]); + } + } else { + // PTE Present? + PageTable = (UINT64 *)(UINTN) (PageTable[PTIndex] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64); + PTIndex = BitFieldRead64(PhysicalAddress, 12, 20); + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + return EFI_NO_MAPPING; + } + + // Consume 4KB from the range + ConvertEncryptionOnPageTableEntry (&PageTable[PTIndex], Operation, AddressEncMask); + PhysicalAddress += SIZE_4KB; + Length -= SIZE_4KB; + } + } + } while (Length); + + // Flush TLB + AsmWriteCr3 (Cr3); + + return EFI_SUCCESS; +} + -- 2.7.4