* [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap @ 2024-01-10 5:38 Zhiguang Liu 2024-01-10 9:09 ` Ni, Ray 2024-01-10 12:15 ` Laszlo Ersek 0 siblings, 2 replies; 9+ messages in thread From: Zhiguang Liu @ 2024-01-10 5:38 UTC (permalink / raw) To: devel Cc: Zhiguang Liu, Ray Ni, Laszlo Ersek, Rahul Kumar, Gerd Hoffmann, Crystal Lee REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4614 Fix issue that IsModified is wrongly set in PageTableMap. Cc: Ray Ni <ray.ni@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Crystal Lee <CrystalLee@ami.com.tw> Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com> --- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c index 36b2c4e6a3..164187f151 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -567,7 +567,10 @@ PageTableLibMapInLevel ( OriginalCurrentPagingEntry.Uint64 = CurrentPagingEntry->Uint64; PageTableLibSetPle (Level, CurrentPagingEntry, Offset, Attribute, &CurrentMask); - if (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry->Uint64) { + if (Modify && (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry->Uint64)) { + // + // The page table entry can be changed by this function only when Modify is true. + // *IsModified = TRUE; } } @@ -609,7 +612,10 @@ PageTableLibMapInLevel ( // Check if ParentPagingEntry entry is modified here is enough. Except the changes happen in leaf PagingEntry during // the while loop, if there is any other change happens in page table, the ParentPagingEntry must has been modified. // - if (OriginalParentPagingEntry.Uint64 != ParentPagingEntry->Uint64) { + if (Modify && (OriginalParentPagingEntry.Uint64 != ParentPagingEntry->Uint64)) { + // + // The page table entry can be changed by this function only when Modify is true. + // *IsModified = TRUE; } -- 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113513): https://edk2.groups.io/g/devel/message/113513 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-10 5:38 [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap Zhiguang Liu @ 2024-01-10 9:09 ` Ni, Ray 2024-01-10 12:15 ` Laszlo Ersek 1 sibling, 0 replies; 9+ messages in thread From: Ni, Ray @ 2024-01-10 9:09 UTC (permalink / raw) To: Liu, Zhiguang, devel@edk2.groups.io Cc: Laszlo Ersek, Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal Reviewed-by: Ray Ni <ray.ni@intel.com> Thanks, Ray > -----Original Message----- > From: Liu, Zhiguang <zhiguang.liu@intel.com> > Sent: Wednesday, January 10, 2024 1:38 PM > To: devel@edk2.groups.io > Cc: Liu, Zhiguang <zhiguang.liu@intel.com>; Ni, Ray <ray.ni@intel.com>; Laszlo > Ersek <lersek@redhat.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Gerd > Hoffmann <kraxel@redhat.com>; Lee, Crystal <crystalLee@ami.com.tw> > Subject: [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in > PageTableMap > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4614 > > Fix issue that IsModified is wrongly set in PageTableMap. > > Cc: Ray Ni <ray.ni@intel.com> > Cc: Laszlo Ersek <lersek@redhat.com> > Cc: Rahul Kumar <rahul1.kumar@intel.com> > Cc: Gerd Hoffmann <kraxel@redhat.com> > Cc: Crystal Lee <CrystalLee@ami.com.tw> > Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com> > --- > UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > index 36b2c4e6a3..164187f151 100644 > --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > @@ -567,7 +567,10 @@ PageTableLibMapInLevel ( > OriginalCurrentPagingEntry.Uint64 = CurrentPagingEntry->Uint64; > PageTableLibSetPle (Level, CurrentPagingEntry, Offset, Attribute, > &CurrentMask); > > - if (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry->Uint64) { > + if (Modify && (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry- > >Uint64)) { > + // > + // The page table entry can be changed by this function only when > Modify is true. > + // > *IsModified = TRUE; > } > } > @@ -609,7 +612,10 @@ PageTableLibMapInLevel ( > // Check if ParentPagingEntry entry is modified here is enough. Except the > changes happen in leaf PagingEntry during > // the while loop, if there is any other change happens in page table, the > ParentPagingEntry must has been modified. > // > - if (OriginalParentPagingEntry.Uint64 != ParentPagingEntry->Uint64) { > + if (Modify && (OriginalParentPagingEntry.Uint64 != ParentPagingEntry- > >Uint64)) { > + // > + // The page table entry can be changed by this function only when Modify > is true. > + // > *IsModified = TRUE; > } > > -- > 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113521): https://edk2.groups.io/g/devel/message/113521 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-10 5:38 [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap Zhiguang Liu 2024-01-10 9:09 ` Ni, Ray @ 2024-01-10 12:15 ` Laszlo Ersek 2024-01-11 2:03 ` Ni, Ray 1 sibling, 1 reply; 9+ messages in thread From: Laszlo Ersek @ 2024-01-10 12:15 UTC (permalink / raw) To: Zhiguang Liu, devel; +Cc: Ray Ni, Rahul Kumar, Gerd Hoffmann, Crystal Lee On 1/10/24 06:38, Zhiguang Liu wrote: > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4614 > > Fix issue that IsModified is wrongly set in PageTableMap. > > Cc: Ray Ni <ray.ni@intel.com> > Cc: Laszlo Ersek <lersek@redhat.com> > Cc: Rahul Kumar <rahul1.kumar@intel.com> > Cc: Gerd Hoffmann <kraxel@redhat.com> > Cc: Crystal Lee <CrystalLee@ami.com.tw> > Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com> > --- > UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > index 36b2c4e6a3..164187f151 100644 > --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c > @@ -567,7 +567,10 @@ PageTableLibMapInLevel ( > OriginalCurrentPagingEntry.Uint64 = CurrentPagingEntry->Uint64; > PageTableLibSetPle (Level, CurrentPagingEntry, Offset, Attribute, &CurrentMask); > > - if (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry->Uint64) { > + if (Modify && (OriginalCurrentPagingEntry.Uint64 != CurrentPagingEntry->Uint64)) { > + // > + // The page table entry can be changed by this function only when Modify is true. > + // > *IsModified = TRUE; > } > } > @@ -609,7 +612,10 @@ PageTableLibMapInLevel ( > // Check if ParentPagingEntry entry is modified here is enough. Except the changes happen in leaf PagingEntry during > // the while loop, if there is any other change happens in page table, the ParentPagingEntry must has been modified. > // > - if (OriginalParentPagingEntry.Uint64 != ParentPagingEntry->Uint64) { > + if (Modify && (OriginalParentPagingEntry.Uint64 != ParentPagingEntry->Uint64)) { > + // > + // The page table entry can be changed by this function only when Modify is true. > + // > *IsModified = TRUE; > } > This function is incredibly complicated, so reviewing this patch is hard, even after reading the bugzilla ticket. The commit message is useless. It should contain a brief description of the problem, and how the fix resolves the problem. The documentation of the PageTableLibMapInLevel() function is wrong, even before this patch. It documents the "IsModified" output-only parameter as follows: "TRUE means page table is modified. FALSE means page table is not modified." This states that "IsModified" is always set on output, to either FALSE or TRUE. Which is an incorrect statement; in reality the caller is expected to pre-set (*IsModified) to FALSE, and PageTableLibMapInLevel() will (conditionally!) perform a FALSE->TRUE transition only. Now, this patch may fix a bug, but it makes the above-described documentation issue worse, by further restricting the condition for said FALSE->TRUE transition. The fix per se looks vaguely reasonable to me (really the function is so complicated that verifying this change from scratch would take me ages), but minimally, the documentation of "IsModified" should certainly be updated too. To something like this: @param[out] IsModified If "Modify" is TRUE on input and the function has actually modified the page table, then set to TRUE on output. Not overwritten otherwise. Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113528): https://edk2.groups.io/g/devel/message/113528 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-10 12:15 ` Laszlo Ersek @ 2024-01-11 2:03 ` Ni, Ray 2024-01-11 8:56 ` Laszlo Ersek 0 siblings, 1 reply; 9+ messages in thread From: Ni, Ray @ 2024-01-11 2:03 UTC (permalink / raw) To: Laszlo Ersek, Liu, Zhiguang, devel@edk2.groups.io Cc: Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal > This function is incredibly complicated, so reviewing this patch is > hard, even after reading the bugzilla ticket. > > The commit message is useless. It should contain a brief description of > the problem, and how the fix resolves the problem. > > The documentation of the PageTableLibMapInLevel() function is wrong, > even before this patch. It documents the "IsModified" output-only > parameter as follows: > > "TRUE means page table is modified. FALSE means page table is not > modified." > > This states that "IsModified" is always set on output, to either FALSE > or TRUE. Which is an incorrect statement; in reality the caller is > expected to pre-set (*IsModified) to FALSE, and PageTableLibMapInLevel() > will (conditionally!) perform a FALSE->TRUE transition only. > > Now, this patch may fix a bug, but it makes the above-described > documentation issue worse, by further restricting the condition for said > FALSE->TRUE transition. Laszlo, thanks for the comments! Though the fixing looks simple, Zhiguang and I did have several rounds of offline discussions regarding how to fix it. When the lib accesses the page table content, CPU would set the "Access" bit in the page entry that points to the page table memory being accessed by the lib. So, even when the "Modify" is FALSE (indicating caller doesn't want the lib to modify the page table), lib code should not modify the page table but CPU still sets the "Access" bit in some of the entries due to the reasons above. I agree it will be better that the commit message carries above details. Zhiguang, Can we update the code to always assign "IsModified"? I thought we did that but it seems not. > > The fix per se looks vaguely reasonable to me (really the function is so > complicated that verifying this change from scratch would take me ages), > but minimally, the documentation of "IsModified" should certainly be > updated too. To something like this: > > @param[out] IsModified If "Modify" is TRUE on input and the function > has actually modified the page table, then > set > to TRUE on output. Not overwritten > otherwise. > > Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113568): https://edk2.groups.io/g/devel/message/113568 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-11 2:03 ` Ni, Ray @ 2024-01-11 8:56 ` Laszlo Ersek 2024-01-15 2:59 ` Zhiguang Liu 2024-01-15 9:43 ` Pedro Falcato 0 siblings, 2 replies; 9+ messages in thread From: Laszlo Ersek @ 2024-01-11 8:56 UTC (permalink / raw) To: devel, ray.ni, Liu, Zhiguang; +Cc: Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal On 1/11/24 03:03, Ni, Ray wrote: >> This function is incredibly complicated, so reviewing this patch is >> hard, even after reading the bugzilla ticket. >> >> The commit message is useless. It should contain a brief description of >> the problem, and how the fix resolves the problem. >> >> The documentation of the PageTableLibMapInLevel() function is wrong, >> even before this patch. It documents the "IsModified" output-only >> parameter as follows: >> >> "TRUE means page table is modified. FALSE means page table is not >> modified." >> >> This states that "IsModified" is always set on output, to either FALSE >> or TRUE. Which is an incorrect statement; in reality the caller is >> expected to pre-set (*IsModified) to FALSE, and PageTableLibMapInLevel() >> will (conditionally!) perform a FALSE->TRUE transition only. >> >> Now, this patch may fix a bug, but it makes the above-described >> documentation issue worse, by further restricting the condition for said >> FALSE->TRUE transition. > > Laszlo, thanks for the comments! > Though the fixing looks simple, Zhiguang and I did have several rounds of offline discussions > regarding how to fix it. > > When the lib accesses the page table content, CPU would set the "Access" bit in the page entry > that points to the page table memory being accessed by the lib. > > So, even when the "Modify" is FALSE (indicating caller doesn't want the lib to modify the page table), > lib code should not modify the page table but CPU still sets the "Access" bit in some of the entries due to > the reasons above. Huh, tricky! Should the comparison explicitly mask out the Accessed bit from each of the "before" page table entry and the "after" one, perhaps? > I agree it will be better that the commit message carries above details. > > Zhiguang, > Can we update the code to always assign "IsModified"? I thought we did that but it seems not. That seems doable by (e.g.) setting (*IsModified) to FALSE right at the top of the function, and then the logic would match the existent comments, I think. However, I've not checked whether callers actually rely on this "summing" logic of the IsModified output parameter -- like call the function a number of times in a row, using a common local variable to receive IsModified, and then check the local variable to see if *any one* of the calls in the loop has modified the page table. Thanks Laszlo > >> >> The fix per se looks vaguely reasonable to me (really the function is so >> complicated that verifying this change from scratch would take me ages), >> but minimally, the documentation of "IsModified" should certainly be >> updated too. To something like this: >> >> @param[out] IsModified If "Modify" is TRUE on input and the function >> has actually modified the page table, then >> set >> to TRUE on output. Not overwritten >> otherwise. >> >> Laszlo > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113598): https://edk2.groups.io/g/devel/message/113598 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-11 8:56 ` Laszlo Ersek @ 2024-01-15 2:59 ` Zhiguang Liu 2024-01-15 17:57 ` Laszlo Ersek 2024-01-15 9:43 ` Pedro Falcato 1 sibling, 1 reply; 9+ messages in thread From: Zhiguang Liu @ 2024-01-15 2:59 UTC (permalink / raw) To: devel@edk2.groups.io, lersek@redhat.com, Ni, Ray Cc: Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal Hi Laszlo, I don't think it is a good idea to explicitly mask out the Accessed/Dirty bit. We can't assume Accessed/Dirty bit are only changed by hardware, because the caller also can change the Accessed/Dirty bit. For API PageTableMap, the IsModified is already set as False in the beginning of the function. For internal function PageTableLibMapInLevel, we don't set IsModified as False in the beginning on purpose, because it keeps the global state of whether the PageTable is changed. I plan to change the comment as below to explicitly explain the behavior: For internal function PageTableLibMapInLevel, the description of IsModified should be: @param[in, out] IsModified change IsModified to True if page table is modified and input parameter Modify is TRUE. For API PageTableMap, the description of IsModified should be: @param[out] IsModified TRUE means page table is modified by software or hardware. FALSE means page table is not modified by software. If the output IsModified is FALSE, there is possibility that the page table is changed by hardware. It is ok because page table can be changed by hardware anytime, and we don't need to Flush TLB. With these comments changed, I don't need to change C code in my patch. BTW, I assume IsModified can be used as an indicator whether the caller need to flush TLB. Do you prefer to change the parameter name to IsFlushTlbNeeded? I am both fine. Thanks Zhiguang > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo > Ersek > Sent: Thursday, January 11, 2024 4:57 PM > To: devel@edk2.groups.io; Ni, Ray <ray.ni@intel.com>; Liu, Zhiguang > <zhiguang.liu@intel.com> > Cc: Kumar, Rahul R <rahul.r.kumar@intel.com>; Gerd Hoffmann > <kraxel@redhat.com>; Lee, Crystal <crystalLee@ami.com.tw> > Subject: Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is > wrongly set in PageTableMap > > On 1/11/24 03:03, Ni, Ray wrote: > >> This function is incredibly complicated, so reviewing this patch is > >> hard, even after reading the bugzilla ticket. > >> > >> The commit message is useless. It should contain a brief description > >> of the problem, and how the fix resolves the problem. > >> > >> The documentation of the PageTableLibMapInLevel() function is wrong, > >> even before this patch. It documents the "IsModified" output-only > >> parameter as follows: > >> > >> "TRUE means page table is modified. FALSE means page table is not > >> modified." > >> > >> This states that "IsModified" is always set on output, to either > >> FALSE or TRUE. Which is an incorrect statement; in reality the caller > >> is expected to pre-set (*IsModified) to FALSE, and > >> PageTableLibMapInLevel() will (conditionally!) perform a FALSE->TRUE > transition only. > >> > >> Now, this patch may fix a bug, but it makes the above-described > >> documentation issue worse, by further restricting the condition for > >> said > >> FALSE->TRUE transition. > > > > Laszlo, thanks for the comments! > > Though the fixing looks simple, Zhiguang and I did have several rounds > > of offline discussions regarding how to fix it. > > > > When the lib accesses the page table content, CPU would set the > > "Access" bit in the page entry that points to the page table memory being > accessed by the lib. > > > > So, even when the "Modify" is FALSE (indicating caller doesn't want > > the lib to modify the page table), lib code should not modify the page > > table but CPU still sets the "Access" bit in some of the entries due to the > reasons above. > > Huh, tricky! > > Should the comparison explicitly mask out the Accessed bit from each of the > "before" page table entry and the "after" one, perhaps? > > > I agree it will be better that the commit message carries above details. > > > > Zhiguang, > > Can we update the code to always assign "IsModified"? I thought we did > that but it seems not. > > That seems doable by (e.g.) setting (*IsModified) to FALSE right at the top of > the function, and then the logic would match the existent comments, I think. > However, I've not checked whether callers actually rely on this "summing" logic > of the IsModified output parameter -- like call the function a number of times > in a row, using a common local variable to receive IsModified, and then check > the local variable to see if *any one* of the calls in the loop has modified the > page table. > > Thanks > Laszlo > > > > >> > >> The fix per se looks vaguely reasonable to me (really the function is > >> so complicated that verifying this change from scratch would take me > >> ages), but minimally, the documentation of "IsModified" should > >> certainly be updated too. To something like this: > >> > >> @param[out] IsModified If "Modify" is TRUE on input and the function > >> has actually modified the page table, then > >> set > >> to TRUE on output. Not overwritten > >> otherwise. > >> > >> Laszlo > > > > > > > > > > > > > > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113787): https://edk2.groups.io/g/devel/message/113787 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-15 2:59 ` Zhiguang Liu @ 2024-01-15 17:57 ` Laszlo Ersek 0 siblings, 0 replies; 9+ messages in thread From: Laszlo Ersek @ 2024-01-15 17:57 UTC (permalink / raw) To: Liu, Zhiguang, devel@edk2.groups.io, Ni, Ray Cc: Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal On 1/15/24 03:59, Liu, Zhiguang wrote: > Hi Laszlo, > > I don't think it is a good idea to explicitly mask out the Accessed/Dirty bit. We can't assume Accessed/Dirty bit are only changed by hardware, because the caller also can change the Accessed/Dirty bit. > > For API PageTableMap, the IsModified is already set as False in the beginning of the function. > For internal function PageTableLibMapInLevel, we don't set IsModified as False in the beginning on purpose, because it keeps the global state of whether the PageTable is changed. > > I plan to change the comment as below to explicitly explain the behavior: > > For internal function PageTableLibMapInLevel, the description of IsModified should be: > @param[in, out] IsModified change IsModified to True if page table is modified and input parameter Modify is TRUE. > > For API PageTableMap, the description of IsModified should be: > @param[out] IsModified TRUE means page table is modified by software or hardware. FALSE means page table is not modified by software. > If the output IsModified is FALSE, there is possibility that the page table is changed by hardware. It is ok because page table can be changed by hardware anytime, and we don't need to Flush TLB. > > With these comments changed, I don't need to change C code in my patch. OK, sounds reasonable to me. Thanks. > > BTW, I assume IsModified can be used as an indicator whether the caller need to flush TLB. Do you prefer to change the parameter name to IsFlushTlbNeeded? I am both fine. I think the new description of the parameter suffices (without renaming the parameter). Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113838): https://edk2.groups.io/g/devel/message/113838 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-11 8:56 ` Laszlo Ersek 2024-01-15 2:59 ` Zhiguang Liu @ 2024-01-15 9:43 ` Pedro Falcato 2024-01-15 18:00 ` Laszlo Ersek 1 sibling, 1 reply; 9+ messages in thread From: Pedro Falcato @ 2024-01-15 9:43 UTC (permalink / raw) To: devel, lersek Cc: ray.ni, Liu, Zhiguang, Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal On Thu, Jan 11, 2024 at 8:56 AM Laszlo Ersek <lersek@redhat.com> wrote: > > On 1/11/24 03:03, Ni, Ray wrote: > >> This function is incredibly complicated, so reviewing this patch is > >> hard, even after reading the bugzilla ticket. > >> > >> The commit message is useless. It should contain a brief description of > >> the problem, and how the fix resolves the problem. > >> > >> The documentation of the PageTableLibMapInLevel() function is wrong, > >> even before this patch. It documents the "IsModified" output-only > >> parameter as follows: > >> > >> "TRUE means page table is modified. FALSE means page table is not > >> modified." > >> > >> This states that "IsModified" is always set on output, to either FALSE > >> or TRUE. Which is an incorrect statement; in reality the caller is > >> expected to pre-set (*IsModified) to FALSE, and PageTableLibMapInLevel() > >> will (conditionally!) perform a FALSE->TRUE transition only. > >> > >> Now, this patch may fix a bug, but it makes the above-described > >> documentation issue worse, by further restricting the condition for said > >> FALSE->TRUE transition. > > > > Laszlo, thanks for the comments! > > Though the fixing looks simple, Zhiguang and I did have several rounds of offline discussions > > regarding how to fix it. > > > > When the lib accesses the page table content, CPU would set the "Access" bit in the page entry > > that points to the page table memory being accessed by the lib. > > > > So, even when the "Modify" is FALSE (indicating caller doesn't want the lib to modify the page table), > > lib code should not modify the page table but CPU still sets the "Access" bit in some of the entries due to > > the reasons above. > > Huh, tricky! > > Should the comparison explicitly mask out the Accessed bit from each of > the "before" page table entry and the "after" one, perhaps? FWIW, clearing the A and D bits off of PTEs requires a TLB flush and, as such, that change would break them. In general: - You need a TLB flush when unmapping a page - You need a TLB flush when changing an already-mapped PTE (unless you tolerate a stale TLB and want to eat a spurious page fault, which is a valid technique) - You don't need a TLB flush when freshly mapping a page (unmapped -> mapped) as x86 doesn't cache non-present PTEs so you shouldn't need to inspect the PTE before and after; in fact, that's erroneous as Intel CPUs can speculatively set the A and D bits (they're slightly more careful since CET rolled around, but as far as I've heard older Intel used to wildly set those bits speculatively) and AMD ones can too (although they cannot speculatively set D). I'd love to give out more feedback on this patch, but I *really* don't understand what any of that function is doing :/ -- Pedro -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113813): https://edk2.groups.io/g/devel/message/113813 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap 2024-01-15 9:43 ` Pedro Falcato @ 2024-01-15 18:00 ` Laszlo Ersek 0 siblings, 0 replies; 9+ messages in thread From: Laszlo Ersek @ 2024-01-15 18:00 UTC (permalink / raw) To: Pedro Falcato, devel Cc: ray.ni, Liu, Zhiguang, Kumar, Rahul R, Gerd Hoffmann, Lee, Crystal On 1/15/24 10:43, Pedro Falcato wrote: > On Thu, Jan 11, 2024 at 8:56 AM Laszlo Ersek <lersek@redhat.com> wrote: >> >> On 1/11/24 03:03, Ni, Ray wrote: >>>> This function is incredibly complicated, so reviewing this patch is >>>> hard, even after reading the bugzilla ticket. >>>> >>>> The commit message is useless. It should contain a brief description of >>>> the problem, and how the fix resolves the problem. >>>> >>>> The documentation of the PageTableLibMapInLevel() function is wrong, >>>> even before this patch. It documents the "IsModified" output-only >>>> parameter as follows: >>>> >>>> "TRUE means page table is modified. FALSE means page table is not >>>> modified." >>>> >>>> This states that "IsModified" is always set on output, to either FALSE >>>> or TRUE. Which is an incorrect statement; in reality the caller is >>>> expected to pre-set (*IsModified) to FALSE, and PageTableLibMapInLevel() >>>> will (conditionally!) perform a FALSE->TRUE transition only. >>>> >>>> Now, this patch may fix a bug, but it makes the above-described >>>> documentation issue worse, by further restricting the condition for said >>>> FALSE->TRUE transition. >>> >>> Laszlo, thanks for the comments! >>> Though the fixing looks simple, Zhiguang and I did have several rounds of offline discussions >>> regarding how to fix it. >>> >>> When the lib accesses the page table content, CPU would set the "Access" bit in the page entry >>> that points to the page table memory being accessed by the lib. >>> >>> So, even when the "Modify" is FALSE (indicating caller doesn't want the lib to modify the page table), >>> lib code should not modify the page table but CPU still sets the "Access" bit in some of the entries due to >>> the reasons above. >> >> Huh, tricky! >> >> Should the comparison explicitly mask out the Accessed bit from each of >> the "before" page table entry and the "after" one, perhaps? > > FWIW, clearing the A and D bits off of PTEs requires a TLB flush and, > as such, that change would break them. I didn't mean to clear the A/D bits inside the actual live PTEs, only in those temporary / helper variables (or even just expressions) that we use for comparing the before/after states. > > In general: > - You need a TLB flush when unmapping a page > - You need a TLB flush when changing an already-mapped PTE (unless > you tolerate a stale TLB and want to eat a spurious page fault, which > is a valid technique) > - You don't need a TLB flush when freshly mapping a page (unmapped -> > mapped) as x86 doesn't cache non-present PTEs > > so you shouldn't need to inspect the PTE before and after; this seems to invite further discussion wrt. what the function is supposed to do at all... > in fact, > that's erroneous as Intel CPUs can speculatively set the A and D bits > (they're slightly more careful since CET rolled around, but as far as > I've heard older Intel used to wildly set those bits speculatively) > and AMD ones can too (although they cannot speculatively set D). What is the error behavior here? Assuming we consider a speculative A/D setting by the hardware, the worst that can happen is that we spuriously flush the TLB. Is that right? Doesn't seem extremely harmful. > > I'd love to give out more feedback on this patch, but I *really* don't > understand what any of that function is doing :/ > Yup. (In general I'm just acknowledging that right now this is quite out of my league...) Thanks, Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113839): https://edk2.groups.io/g/devel/message/113839 Mute This Topic: https://groups.io/mt/103636407/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=- ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-01-16 7:30 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-01-10 5:38 [edk2-devel] [PATCH] UefiCpuPkg: Fix issue that IsModified is wrongly set in PageTableMap Zhiguang Liu 2024-01-10 9:09 ` Ni, Ray 2024-01-10 12:15 ` Laszlo Ersek 2024-01-11 2:03 ` Ni, Ray 2024-01-11 8:56 ` Laszlo Ersek 2024-01-15 2:59 ` Zhiguang Liu 2024-01-15 17:57 ` Laszlo Ersek 2024-01-15 9:43 ` Pedro Falcato 2024-01-15 18:00 ` Laszlo Ersek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox