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.83]) by mx.groups.io with SMTP id smtpd.web08.15130.1634672421098861766 for ; Tue, 19 Oct 2021 12:40:21 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=j+YK/Ay0; 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.83, mailfrom: brijesh.singh@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Z/uRu2t23aEQynOknB8VOl9Il16cJilR30rebj8FPy/JUYuWxUi4gCf7w/QBsBPSyI5s8aucAh5uvs5Wcg6aL5vPVLv2U+U23msZJCnFvr/JwNO+v/H9lgNUI2u4GNR7bKYNOUg6URyW3yCX+IL9e+RO8wZR1bBbMvRzM+FV6DEcbLxbnS6bBqynOfK5eToaBtCW0yvSrq9c/W4jCRj6oiTabD0V71JbywmkgQy552elJOU9sAn9Ecusz60LCAmcIk5R1A9JbYjVTe65Oj7/GZ/wX9FDDOz/eF8d1HgEoXSX498IRqgbzRG3q8NDGZEP+lC5tmZ2w9rFYqqTQHMayg== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xVocjAg1Pc5sF9fM0Ch9XKX75QfupYvI0/npHBj+Qmw=; b=Bn7/VCFebKxkcmUSAe073DV8sBfcNDvynNu+nL5UzRz5GIeAbchSwzYCIWPiNUGV3Mt9R7eYoSf0FG8LUVdWdX6cOWvxVqrhH1DFF4GXn7fQ980qEWvNp4jJByXvDHc/OOf5i9rADHgR2HDovkh6F7+jDBjWaNkck9IQWWglkNRALOFEi57FnqzfwkvudvkH8/eAKwom55G7c+X6FlBum1ANhTn5FRueaknFIYFD47QRclQB95xwjmjVUALP9US8PiG0EIfS9MzzPKG3SU47XuNOuANhDdh4mXsdqf3ErclgjN9mKqBNsF0WV8lSICFNKjzQW5UaOIqMRQzCEfWPqA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); 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=xVocjAg1Pc5sF9fM0Ch9XKX75QfupYvI0/npHBj+Qmw=; b=j+YK/Ay0K5fLNgGfyf97oG0ebK33ZZVXfgHBv9adx3oYC64qHCb5tcN1C53heNWNybR3+HgdmNo6t6zoPxeYs7ej5oy8xKwf1Y+8HMHAv1QB2CNJT5qTQLKF4RsQ+D9eed/xWqNu7SoD8VI6fS3SiCR+9AlgNpLRbscNaeBv5f4= Received: from MW4PR03CA0066.namprd03.prod.outlook.com (2603:10b6:303:b6::11) by DM6PR12MB4877.namprd12.prod.outlook.com (2603:10b6:5:1bb::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.17; Tue, 19 Oct 2021 19:40:14 +0000 Received: from CO1NAM11FT028.eop-nam11.prod.protection.outlook.com (2603:10b6:303:b6:cafe::e8) by MW4PR03CA0066.outlook.office365.com (2603:10b6:303:b6::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4628.15 via Frontend Transport; Tue, 19 Oct 2021 19:40:08 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; Received: from SATLEXMB04.amd.com (165.204.84.17) by CO1NAM11FT028.mail.protection.outlook.com (10.13.175.214) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4608.15 via Frontend Transport; Tue, 19 Oct 2021 19:40:08 +0000 Received: from sbrijesh-desktop.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Tue, 19 Oct 2021 14:40:03 -0500 From: "Brijesh Singh" To: CC: James Bottomley , Min Xu , "Jiewen Yao" , Tom Lendacky , "Jordan Justen" , Ard Biesheuvel , Erdem Aktas , "Michael Roth" , Gerd Hoffmann , Brijesh Singh , Michael Roth , Jiewen Yao Subject: [PATCH v10 17/32] OvmfPkg/MemEncryptSevLib: add support to validate > 4GB memory in PEI phase Date: Tue, 19 Oct 2021 14:39:19 -0500 Message-ID: <20211019193934.1052465-18-brijesh.singh@amd.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211019193934.1052465-1-brijesh.singh@amd.com> References: <20211019193934.1052465-1-brijesh.singh@amd.com> MIME-Version: 1.0 Return-Path: brijesh.singh@amd.com X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9643b247-b69d-4e00-689b-08d99338422e X-MS-TrafficTypeDiagnostic: DM6PR12MB4877: 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: XKOB+MyAcRvyaFu2OgTPeg6ytzPeXA6taPc2sARTRUPxsq8PsC8B83Zfe1S8VrNcvKIue+//2MkVknO2U5mdxq9zGpUbJ+2BKr81x24w68P0oh99PsCIepHHlnOMEHaprnSih59e2XgxW3/sNBlL5gzEppBBpO6jK71V7E3Mk5FsjPU5HH0CCHQFJ7ZlOfOyOr25Ql8TsrbHifgsAvkN4+0lB0tX6Zy++iPeOD6KBkHqhpEn5pXA9Z4bdjUBsMpyaOxSJwJ1X92rdAV47SCntBpVi/qWyTF3PqV9tMsBVdaDJ9Y/QLTRYVQAKpbq2Wl/+d6dnXOd1eSqkAzdimzmX+NcCGKeB5mIx57djcquL4IdO85TcJy5Zd1nYnu/XUr5mbcwWA6fpJ/q1m1t9Hxrb6MxZpn3GwLIFvM0wE7UfpawG1ZCBv6eQRY8zWURYlvBxNSPjMsslKNj4rm1r6eYbYFe4ACV7ABK7ps/6N3nhTY4YemzsgER8vHAuilo0U6PAxJbRYYVYg/xz8Ih9AqGxt/OGvwHAKaGME1oq5dhiy0A4r2XCJed5NEKHB3FkLwyU5vG78s2J3e4GEJ2F6t9WDRNWT6LWnt6u63xxdplg9Q09oo3kvscf91WbdZtQzr0lqw0VTgkz3BY1Rs5L/CiXmF4WP4eWGMb1eqP59XEi+D+VVCfqd4/5FZ/4yq3ENLM0szTzB8N+PVvv0VSw+bRMoF2nqbBEB/W12HF+2u+BD6nex/BEJyTQTFwOa6nUeryBuUX7JKRt0joqAV1VWZEx9ONEQUpAaB5sYQiyFsux2qQMCrr8yojeYUHpDGka3at X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(4636009)(46966006)(36840700001)(82310400003)(36756003)(186003)(426003)(336012)(86362001)(26005)(44832011)(2616005)(16526019)(54906003)(1076003)(316002)(966005)(356005)(6666004)(508600001)(6916009)(2906002)(7696005)(5660300002)(47076005)(8936002)(19627235002)(70206006)(70586007)(4326008)(81166007)(15650500001)(8676002)(36860700001)(83380400001)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Oct 2021 19:40:08.5786 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9643b247-b69d-4e00-689b-08d99338422e X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT028.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4877 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 | 24 ++++ .../X64/PeiDxeVirtualMemory.c | 115 ++++++++++++++++++ .../X64/PeiSnpSystemRamValidate.c | 22 ++++ 3 files changed, 161 insertions(+) diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h b/Ovm= fPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h index 21bbbd1c4f9c..9e5cdae25245 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/X64/VirtualMemory.h @@ -143,4 +143,28 @@ InternalMemEncryptSevClearMmioPageEncMask ( IN PHYSICAL_ADDRESS PhysicalAddress, IN UINTN Length ); + +/** + Create 1GB identity mapping for the specified virtual address range. + + The function is preliminary used by the SEV-SNP page state change + APIs to build the page table required before issuing the PVALIDATE + instruction. The function must be removed after the EDK2 core is + enhanced to do the lazy validation. + + @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 cea7ecf96563..ee8b5bc8011f 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; @@ -69,6 +72,7 @@ MemEncryptSevSnpPreValidateSystemRam ( { PHYSICAL_ADDRESS EndAddress; SNP_PRE_VALIDATED_RANGE OverlapRange; + EFI_STATUS Status; =20 if (!MemEncryptSevSnpIsEnabled ()) { return; @@ -76,6 +80,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.25.1