From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.groups.io with SMTP id smtpd.web10.2590.1604340321876935632 for ; Mon, 02 Nov 2020 10:05:22 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NXvLVpt3; spf=pass (domain: redhat.com, ip: 216.205.24.124, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1604340321; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VF0eVbFtThvjpD7y8jGf19rIwIAbVv/GLZrDOvJjbbQ=; b=NXvLVpt3FbFKjTbSHRkp57ItvAHOW3M1euX9LyWEaFKGVfPp6dPSVEdrFirJkCkfz5joz1 78Lm/jXFT1+oMYJiE0YiRTTEC5sfJqv94UwUWBjcay8sby6Kdk5YnlrR2Xk4xs7ysB6Etp cR5YEnzJs3wqpPepjOUN9nbCwdMSDHs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-239-0w-wgv1LPQCZgyGmEMEzAA-1; Mon, 02 Nov 2020 13:05:13 -0500 X-MC-Unique: 0w-wgv1LPQCZgyGmEMEzAA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A86D059; Mon, 2 Nov 2020 18:05:11 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-112-126.ams2.redhat.com [10.36.112.126]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1031B5B4D7; Mon, 2 Nov 2020 18:05:09 +0000 (UTC) Subject: Re: [PATCH v3 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: Return level paging type for Internal CR3 To: Sheng Wei , devel@edk2.groups.io Cc: Eric Dong , Ray Ni , Rahul Kumar , Jiewen Yao References: <20201102045330.3540-1-w.sheng@intel.com> <20201102045330.3540-3-w.sheng@intel.com> From: "Laszlo Ersek" Message-ID: <7961ac60-2b3e-a43a-34b6-5562081d780a@redhat.com> Date: Mon, 2 Nov 2020 19:05:09 +0100 MIME-Version: 1.0 In-Reply-To: <20201102045330.3540-3-w.sheng@intel.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lersek@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 11/02/20 05:53, Sheng Wei wrote: > When the functions called from entrypoint the page table is > set to mInternalCr3, mInternalIs5LevelPaging reflects > the page table type pointed by mInternalCr3. > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3015 > > Change-Id: I9e44c6385a05930850f5ba60d10ed3e391b628bb (1) None of the patches should contain such a "Change-Id" line; they are meaningless for upstream edk2. They can be removed by the maintainer just before merging, of course. (2) However, I still have absolutely no idea what the problem is. Ray provided some great feedback here: https://edk2.groups.io/g/devel/message/66617 In particular: Better to explain the case when the functions called from entrypoint the page table is set to mInternalCr3, gSmmFeatureEnable5LevelPaging reflects the page table type pointed by mInternalCr3. And this has not been *explained*. The commit message should include a reminder *why* we sometimes use "mInternalCr3" (i.e., when it is nonzero), and why we use the CR3 register in other cases. This reminder is not related to the change in this patch, it should re-state the *original* use case for "mInternalCr3". And then in the next paragraph, the commit message should explain that, *IF* we use "mInternalCr3", rather than CR3, *then* accessing CR4 for 5-level paging is wrong -- because in that case, we should save the 5-level paging status similarly (I guess?) to how we save "mInternalCr3". So, on the surface, the change seems to make sense, but without knowing why we use "mInternalCr3" in the first place, I find it difficult to reason about this change. ... - According to git-blame, "mInternalCr3" comes from edk2 commit 3eb69b081c68 ("UefiCpuPkg/PiSmmCpu: Add Shadow Stack Support for X86 SMM.", 2019-02-28), and it is related to . - Also according to git-blame, the original "Enable5LevelPaging" assignment, based on "Cr4.Bits.LA57", comes from commit 4eee0cc7cc0d ("UefiCpuPkg/PiSmmCpu: Enable 5 level paging when CPU supports", 2019-07-12), related to . Commit 3eb69b081c68 (the "CET ShadowStack" feature) *precedes* commit 4eee0cc7cc0d (the 5-level paging feature) in the git commit history. Therefore the bug was introduced commit 4eee0cc7cc0d -- the 5-level paging enablement did not take CET ShadowStack support in consideration. In other words, this patch fixes (or "completes") 5-level paging support for "CET ShadowStack". Is that correct? If so, then *WHY* is none of the expressions "CET ShadowStack" and "5-level paging" present in any of the subject lines? Why are there no references to commits 3eb69b081c68 and 4eee0cc7cc0d in the commit messages? Why does Bug 3015 not reference Bug 1521 and Bug 1946? After all, if I understand correctly, this patch covers a corner case in the intersection of two features. Why is that not documented clearly? I want to see a statement such as "if we are using a shadow stack, then we need to use a CR4 value that matches the shadow stack, for determining whether 5-level paging is enabled or not". Or *something* like this. > Signed-off-by: Sheng Wei > Cc: Eric Dong > Cc: Ray Ni > Cc: Laszlo Ersek > Cc: Rahul Kumar > Cc: Jiewen Yao > --- > UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h | 10 ++++++ > UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 42 ++++++++++++++++++++-- > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 2 ++ > 3 files changed, 51 insertions(+), 3 deletions(-) > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > index 7fb3a2d9e4..3eb6af62a7 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h > @@ -951,6 +951,16 @@ GetPageTableBase ( > VOID > ); > > +/** > + This function set the internal page table type to 5 level paging or 4 level paging. > + > + @param Is5LevelPaging TRUE means 5 level paging. FALSE means 4 level paging. > +**/ > +VOID > +SetPageTableType ( > + IN BOOLEAN Is5LevelPaging > + ); > + > /** > This function sets the attributes for the memory region specified by BaseAddress and > Length from their current attributes to the attributes specified by Attributes. > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > index d67f036aea..91c0fd6587 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > @@ -33,6 +33,7 @@ PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = { > }; > > UINTN mInternalCr3; > +BOOLEAN mInternalIs5LevelPaging = FALSE; > > /** > Set the internal page table base address. > @@ -65,6 +66,43 @@ GetPageTableBase ( > return (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64); > } > > +/** > + This function set the internal page table type to 5 level paging or 4 level paging. > + > + @param Is5LevelPaging TRUE means 5 level paging. FALSE means 4 level paging. > +**/ > +VOID > +SetPageTableType ( > + IN BOOLEAN Is5LevelPaging > + ) > +{ > + mInternalIs5LevelPaging = Is5LevelPaging; > +} > + > +/** > + Return if the page table is 5 level paging. > + > + @return TRUE The page table base is 5 level paging. > + @return FALSE The page table base is 4 level paging. > +**/ > +STATIC > +BOOLEAN > +Is5LevelPageTableBase ( > + VOID > + ) > +{ > + IA32_CR4 Cr4; > + > + // If mInternalCr3 is non zero, it will not use the page table from CR3. > + // So, return the page level type from mInternalIs5LevelPaging instead of the CR4 LA57 bit. (3) Invalid comment style. Missing empty "//" lines before and after. > + if (mInternalCr3 != 0) { > + return mInternalIs5LevelPaging; > + } > + > + Cr4.UintN = AsmReadCr4 (); > + return (BOOLEAN) (Cr4.Bits.LA57 == 1); > +} > + > /** > Return length according to page attributes. > > @@ -131,7 +169,6 @@ GetPageTableEntry ( > UINT64 *L3PageTable; > UINT64 *L4PageTable; > UINT64 *L5PageTable; > - IA32_CR4 Cr4; > BOOLEAN Enable5LevelPaging; > > Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK; > @@ -140,8 +177,7 @@ GetPageTableEntry ( > Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK; > Index1 = ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK; > > - Cr4.UintN = AsmReadCr4 (); > - Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1); > + Enable5LevelPaging = Is5LevelPageTableBase(); (4) Missing space character before the opening parenthesis. > > if (sizeof(UINTN) == sizeof(UINT64)) { > if (Enable5LevelPaging) { > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > index 810985df20..6f2f4adb7d 100644 > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > @@ -387,6 +387,8 @@ SmmInitPageTable ( > SetSubEntriesNum (Pml4Entry, 3); > PTEntry = Pml4Entry; > > + SetPageTableType(m5LevelPagingNeeded); (5) Missing space character before the opening parenthesis. > + > if (m5LevelPagingNeeded) { > // > // Fill PML5 entry > Laszlo