From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.49]) by mx.groups.io with SMTP id smtpd.web11.855.1631557212637222350 for ; Mon, 13 Sep 2021 11:20:12 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=udzYk//A; 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.93.49, mailfrom: brijesh.singh@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SMjE/9ZIXZQFGUyQgzZDEzpvvQetrCKX/e+H3FdLic0M06lIrHIXk4dcgwfBrkC1bBdCX+nJ8njfIE/1o2PJ71S7sDz03nDQvD0LbAG/H14pgZDiPHvwuKctcy38SLAKiB6YZA1zBp9yFLkBaWQ5QWtYfPxzUHxTOpDdfpEilo/7gIBngOg2+FlynE0Dg1hls3IhnL7NYcwYf3dfhw5D6xeOjGacTqLywp8a7tN5fVmX5CdnCXJxow4aeEupzH4weobn9rUPnu3N7yyrshcOnZFh+P6RsDAL0IzJH4Hc6ITiF4Dcb+RQt6jhMzCVTXiIPqRIlp0vUQ3Za+vz+pUipg== 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; bh=RqtmB4yFd7gT9bCLAvKkuYlPCviall+hyPk2dW4WE7o=; b=JoZwU/D1upg6NrNgUHHiwmZfs75Ry0RLpF8bmbgsymMU7TmS+euQcu5YUkdJHHMuoa6ongS41A7E2Ofc/Z2cG5AYVbVixQQcsqM3/s9UkCGWbpcVTruWCi374TfkBWFgdNIriM/Oos3tBrT1PpOQXkOnhSeWxrg4PaoGa+932CGewFzXpfdsqBKHJGKLRIer6qTH0GopovUD5RENqCpgqhjZkxcjX2tFT4JBgXvWAYpLeqCit/BFf1NStQUCXqY6eKMp4Y85sbTA7NEaiL0geu0NE3EUPqn8qK1qm72bXAttT+tAyuHtWASu4SF4H75yGCrtYrEoOY4cufJf/nhymw== 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=RqtmB4yFd7gT9bCLAvKkuYlPCviall+hyPk2dW4WE7o=; b=udzYk//A0jw86r2l3hquZdAoeke5JvMngKTwYmdWnATOOcB+/9rCNSCpiHJjGojQ+YpbCMrCyjQViFEjqpnkGw1VJOIY93wZz8LI9honjEgPb8h1prWDirh9Cr0b51C0uVaMNXpO6BdOlp/me7BKqsYoOuoU67B567Us9qrNUZI= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=amd.com; Received: from SN6PR12MB2718.namprd12.prod.outlook.com (2603:10b6:805:6f::22) by SA0PR12MB4557.namprd12.prod.outlook.com (2603:10b6:806:9d::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4500.17; Mon, 13 Sep 2021 18:20:11 +0000 Received: from SN6PR12MB2718.namprd12.prod.outlook.com ([fe80::78b7:7336:d363:9be3]) by SN6PR12MB2718.namprd12.prod.outlook.com ([fe80::78b7:7336:d363:9be3%6]) with mapi id 15.20.4500.019; Mon, 13 Sep 2021 18:20:11 +0000 From: "Brijesh Singh" To: devel@edk2.groups.io CC: James Bottomley , Min Xu , Jiewen Yao , Tom Lendacky , Jordan Justen , Ard Biesheuvel , Erdem Aktas , Michael Roth , Gerd Hoffmann , Brijesh Singh , Michael Roth Subject: [PATCH v7 16/31] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Date: Mon, 13 Sep 2021 13:19:26 -0500 Message-ID: <20210913181941.23405-17-brijesh.singh@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210913181941.23405-1-brijesh.singh@amd.com> References: <20210913181941.23405-1-brijesh.singh@amd.com> X-ClientProxiedBy: SA9P221CA0012.NAMP221.PROD.OUTLOOK.COM (2603:10b6:806:25::17) To SN6PR12MB2718.namprd12.prod.outlook.com (2603:10b6:805:6f::22) Return-Path: brijesh.singh@amd.com MIME-Version: 1.0 Received: from sbrijesh-desktop.amd.com (165.204.77.1) by SA9P221CA0012.NAMP221.PROD.OUTLOOK.COM (2603:10b6:806:25::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4500.14 via Frontend Transport; Mon, 13 Sep 2021 18:20:10 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9742a162-8f5e-45e8-f7cf-08d976e31fb0 X-MS-TrafficTypeDiagnostic: SA0PR12MB4557: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8273; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LhQrfChoybo4IbdvfJHzf7BBqICAvg7RZ+5gc2ZnDmZXBlbiS1fl7gQjlFNCUJjd/bBLLNJzr8RrXTxFoF3VrrfBHWHmo1P9YN+lEUelkDi/s4YRsI+EfUakE5EvtPO+TfZSHwZ9fNj075VGlRs1C4Te4qknWLzR15X9aIJltPBvDb0Y6FQaP4xvo06DSbfMw/K+9Dk0c1jLF6nZas1f9QoNnBUxwS/A5lvweLyyqClZTQz/MH2x683gUo32DstFQjXNZw0Tg5kLIC/QJDY407r9v0MPyyFY/IU7KqJht+6WkU3oyRRpesQXuAxKjBtYWdN9KaF5uSeWlu0DDywZxHrWRXlvbd+i/K2EBhxUJHZmIr+x+rCmpfzIawJPepvU8y9qQC/LUXUcfBhCAy7P6+VsyVXSJ7pezGtAsqBD1xFiOPeQ/uxE/opH3vyslB8pf1xA7rEsY3Qu/HPN+0RpA5aj5tkTCNjcrLlN02r6tji0KXgz1uHLcztDGEqYLSy+8PmPuap+kj3A9UBK+JGSjhf+nlWF8J1uJDD4nSgiKS/34k7vQxAExI22c8kRevU+eToIIGEEtsdLd3oeF117XUWP3CrHkh8kVxLJ42Iuy6aUivzMhKGg6asJFBIyd6abtAoz7nQD+rGCj3tNGNcGK8FGlId7jlkdu+6ka8o5gLzOXvYN+b2SmT5iN3arWnJTZdl6Bo/sz8Kb46v3JSfOrSb8ZOHM5p59cY5gosJk1ZQUa0/+uy2Vdrz/wnZXEC1y4/z7AXZaROL/+isjEMqMmuM7t106URdQuxAarVkSLFE= 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:(4636009)(396003)(136003)(366004)(346002)(39860400002)(376002)(478600001)(86362001)(7696005)(6916009)(966005)(316002)(52116002)(54906003)(15650500001)(44832011)(83380400001)(38350700002)(66556008)(5660300002)(36756003)(19627235002)(1076003)(4326008)(2906002)(186003)(956004)(26005)(8936002)(8676002)(2616005)(6486002)(38100700002)(6666004)(66476007)(66946007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?zsGeNCvPreIqVwgb+PvTbMd79WbEeLb1S74za6/VKK6UMz2yKPBNnlEkYFHC?= =?us-ascii?Q?7wt7WHxf3OAwarvtHKTGiYg9sXPR1xDGpQToXQXeuVw+mJyXPlLM8vEMgzBq?= =?us-ascii?Q?TSaTB0brpORVM8kBkOmXHnCRQyUVsUvNiaUbDI8u7XN94DiWrT1KtTHWK01r?= =?us-ascii?Q?Cdk37v+4mipnM3SV2GRQB7MmdJ4+wgNPW3C4RBwfV5oQg78HGSYOyY2mdvBo?= =?us-ascii?Q?SUph5r2EJz6ZpAxsmjMPibl+YbiFtDDwAKXRpV3LxTbwM4Un/m8G0Vgq3N/h?= =?us-ascii?Q?SmmS4Kw9fntM1wqtu3InClDTgSxVxJ4D4YPseMwQPYX7xbgmJgFzLD3UbBi9?= =?us-ascii?Q?xoNMdQa9im/4Gp6xFaFqVpBGckOtbuJIJxcUH9WJue5dgjnNUEwo2duiGy2j?= =?us-ascii?Q?ufJzYk9BurIFGrYrWFpPPRVTwxX6+yc2qQaILtn4fxFhaDdKAyBJtR5H/ew1?= =?us-ascii?Q?PZ+6NmDTJ4i0Menel1yVerWnll0W5amq4Ypxf0jPktNy4S25NgSx1llgFVer?= =?us-ascii?Q?NKCOBgFSV6QWw/KhTL5myNPt89ezbMrmjb8cHXobvX4u1FBPYofNHmFj/J3K?= =?us-ascii?Q?mk2T5GhFfDem8H1/Nn0gfx7iCDVeuxiKhBieXmJVQu2tL511ZOvlJl0gqI/+?= =?us-ascii?Q?Er5uBQahIw+QkdUVwGyLg9BT98R1RTP9oPs4yzDCgvnge1UltA7uCAG1+tRP?= =?us-ascii?Q?FMYS6CUkCLgpU5YKFsrxRs+Tdi0i9gxBQ3pZelAMB2PqsLo9Bsl6TF+wJua2?= =?us-ascii?Q?RdDOEHZNHD8LHimp6pQi6nL++GaDZzyr1oZ/TDLfUD4xALQI6unynWNNCBFx?= =?us-ascii?Q?NwppYSdhUGnNwF1a+gGlAtrQkwRTNRrrdlm8akqxXyQiCNx5AXJXwEIX4y1v?= =?us-ascii?Q?K+TCV0EgqojEkeVbxBaIA7CrX61qObjXnxh454+54AtzRefwZUC9x7xWZdE1?= =?us-ascii?Q?WtkuNrUTQWmIRGqLXP8mFFVxZwDkOBiRQb7Ee7nn5AO5bKpSoN3c5zMfv4El?= =?us-ascii?Q?V1ULT+bdU7sQgEFgTHZ+ckJC0kqgp4bYu6XVVIcjkyAw1McuvwwE9cXHMPb3?= =?us-ascii?Q?EIcrP9IfpIJQZcQUt0sKuBYPlRBk39lR5n5Kg3JYKVUyocjMifZwhm0A/D1s?= =?us-ascii?Q?MXmrzZCtXjoEUM1kUrrTFK/ogp8yqp2p19NCUPQt+fZU2HdQofCH3/4OgT6u?= =?us-ascii?Q?MWPiRwIUbYwP+F5EnPbKG0LVqglDgp5SVEaCRjwEv6gUVv+atoZatWYdTGTe?= =?us-ascii?Q?H0brGQWboSpLyF2+TMYTMouI7SwzMR0I0o3vEcarlnNsqUURcVgvryvPq28x?= =?us-ascii?Q?ye28CcNEO1hPCEBQH6lx/3qY?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9742a162-8f5e-45e8-f7cf-08d976e31fb0 X-MS-Exchange-CrossTenant-AuthSource: SN6PR12MB2718.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Sep 2021 18:20:11.2530 (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: yJdpyR388PD8Xz70zNxxKAAQJ/6v4zhgmk+quCTt5oq7Cz+/7mJ6ktz+25bZaPL9nqOweXYp5IQ5mY83kX7v2w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB4557 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3275 The initial page built during the SEC phase is used by the MemEncryptSevSnpValidateSystemRam() for the system RAM validation. The page validation process requires using the PVALIDATE instruction; the instruction accepts a virtual address of the memory region that needs to be validated. If hardware encounters a page table walk failure (due to page-not-present) then it raises #GP. The initial page table built in SEC phase address up to 4GB. Add an internal function to extend the page table to cover > 4GB. The function builds 1GB entries in the page table for access > 4GB. This will provide the support to call PVALIDATE instruction for the virtual address > 4GB in PEI phase. Cc: Michael Roth Cc: James Bottomley Cc: Min Xu Cc: Jiewen Yao Cc: Tom Lendacky Cc: Jordan Justen Cc: Ard Biesheuvel Cc: Erdem Aktas Cc: Gerd Hoffmann Acked-by: Jiewen Yao Signed-off-by: Brijesh Singh --- .../BaseMemEncryptSevLib/X64/VirtualMemory.h | 19 +++ .../X64/PeiDxeVirtualMemory.c | 115 ++++++++++++++++++ .../X64/PeiSnpSystemRamValidate.c | 22 ++++ 3 files changed, 156 insertions(+) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/Ovm= fPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h index 21bbbd1c4f9c..aefef68c30c0 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h @@ -143,4 +143,23 @@ InternalMemEncryptSevClearMmioPageEncMask ( IN PHYSICAL_ADDRESS PhysicalAddress, IN UINTN Length ); + +/** + Create 1GB identity mapping for the specified virtual address range. + + @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use + current CR3) + @param[in] VirtualAddress Virtual address + @param[in] Length Length of virtual address range + + @retval RETURN_INVALID_PARAMETER Number of pages is zero. + +**/ +RETURN_STATUS +EFIAPI +InternalMemEncryptSevCreateIdentityMap1G ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN UINTN Length + ); #endif diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c= b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c index c696745f9d26..f146f6d61cc5 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiDxeVirtualMemory.c @@ -536,6 +536,121 @@ EnableReadOnlyPageWriteProtect ( AsmWriteCr0 (AsmReadCr0() | BIT16); } =20 +RETURN_STATUS +EFIAPI +InternalMemEncryptSevCreateIdentityMap1G ( + IN PHYSICAL_ADDRESS Cr3BaseAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN UINTN Length + ) +{ + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + UINT64 PgTableMask; + UINT64 AddressEncMask; + BOOLEAN IsWpEnabled; + RETURN_STATUS Status; + + // + // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnin= gs. + // + PageMapLevel4Entry =3D NULL; + + DEBUG (( + DEBUG_VERBOSE, + "%a:%a: Cr3Base=3D0x%Lx Physical=3D0x%Lx Length=3D0x%Lx\n", + gEfiCallerBaseName, + __FUNCTION__, + Cr3BaseAddress, + PhysicalAddress, + (UINT64)Length + )); + + if (Length =3D=3D 0) { + return RETURN_INVALID_PARAMETER; + } + + // + // Check if we have a valid memory encryption mask + // + AddressEncMask =3D InternalGetMemEncryptionAddressMask (); + if (!AddressEncMask) { + return RETURN_ACCESS_DENIED; + } + + PgTableMask =3D AddressEncMask | EFI_PAGE_MASK; + + + // + // Make sure that the page table is changeable. + // + IsWpEnabled =3D IsReadOnlyPageWriteProtected (); + if (IsWpEnabled) { + DisableReadOnlyPageWriteProtect (); + } + + Status =3D EFI_SUCCESS; + + while (Length) + { + // + // If Cr3BaseAddress is not specified then read the current CR3 + // + if (Cr3BaseAddress =3D=3D 0) { + Cr3BaseAddress =3D AsmReadCr3(); + } + + PageMapLevel4Entry =3D (VOID*) (Cr3BaseAddress & ~PgTableMask); + PageMapLevel4Entry +=3D PML4_OFFSET(PhysicalAddress); + if (!PageMapLevel4Entry->Bits.Present) { + DEBUG (( + DEBUG_ERROR, + "%a:%a: bad PML4 for Physical=3D0x%Lx\n", + gEfiCallerBaseName, + __FUNCTION__, + PhysicalAddress + )); + Status =3D RETURN_NO_MAPPING; + goto Done; + } + + PageDirectory1GEntry =3D (VOID *)( + (PageMapLevel4Entry->Bits.PageTableBaseAddres= s << + 12) & ~PgTableMask + ); + PageDirectory1GEntry +=3D PDP_OFFSET(PhysicalAddress); + if (!PageDirectory1GEntry->Bits.Present) { + PageDirectory1GEntry->Bits.Present =3D 1; + PageDirectory1GEntry->Bits.MustBe1 =3D 1; + PageDirectory1GEntry->Bits.MustBeZero =3D 0; + PageDirectory1GEntry->Bits.ReadWrite =3D 1; + PageDirectory1GEntry->Uint64 |=3D (UINT64)PhysicalAddress | AddressE= ncMask; + } + + if (Length <=3D BIT30) { + Length =3D 0; + } else { + Length -=3D BIT30; + } + + PhysicalAddress +=3D BIT30; + } + + // + // Flush TLB + // + CpuFlushTlb(); + +Done: + // + // Restore page table write protection, if any. + // + if (IsWpEnabled) { + EnableReadOnlyPageWriteProtect (); + } + + return Status; +} =20 /** This function either sets or clears memory encryption bit for the memory diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValida= te.c b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c index eae7a31773a4..a0803e1255dc 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/PeiSnpSystemRamValidate.c @@ -10,9 +10,12 @@ =20 #include #include +#include +#include #include =20 #include "SnpPageStateChange.h" +#include "VirtualMemory.h" =20 typedef struct { UINT64 StartAddress; @@ -105,6 +108,7 @@ MemEncryptSevSnpPreValidateSystemRam ( { PHYSICAL_ADDRESS EndAddress; SNP_PRE_VALIDATED_RANGE OverlapRange; + EFI_STATUS Status; =20 if (!MemEncryptSevSnpIsEnabled ()) { return; @@ -112,6 +116,24 @@ MemEncryptSevSnpPreValidateSystemRam ( =20 EndAddress =3D BaseAddress + EFI_PAGES_TO_SIZE (NumPages); =20 + // + // The page table used in PEI can address up to 4GB memory. If we are as= ked to + // validate a range above the 4GB, then create an identity mapping so th= at the + // PVALIDATE instruction can execute correctly. If the page table entry = is not + // present then PVALIDATE will #GP. + // + if (BaseAddress >=3D SIZE_4GB) { + Status =3D InternalMemEncryptSevCreateIdentityMap1G ( + 0, + BaseAddress, + EFI_PAGES_TO_SIZE (NumPages) + ); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + CpuDeadLoop (); + } + } + while (BaseAddress < EndAddress) { // // Check if the range overlaps with the pre-validated ranges. --=20 2.17.1