On Sat, May 14, 2022 at 10:13:54PM +0200, He He4 Huang wrote: > iPXE added a workaround to raise TPL to TPL_CALLBACK always, but it > would cause UEFI firmware exit boot service callback with the same TPL > level cannot be executed. Worse, some UEFI modules set a pointer at exit > boot service callback and use later, then will encounter exception / > hang for invalid pointer which is not set to a correct one since the > exit boot service callback is not executed. > > The solution is to restore the TPL to the original one but not always > set it to TPL_CALLBACK. > --- > src/interface/efi/efi_timer.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/src/interface/efi/efi_timer.c b/src/interface/efi/efi_timer.c > index 6427eb1d..24c506fc 100644 > --- a/src/interface/efi/efi_timer.c > +++ b/src/interface/efi/efi_timer.c > @@ -133,11 +133,18 @@ static unsigned long efi_currticks ( void ) { > * EFI's violation of this assumption by falling back to a > * simple free-running monotonic counter during shutdown. > */ > + EFI_TPL Efi_OldTPL; > + Efi_OldTPL=0; > if ( efi_shutdown_in_progress ) { > efi_jiffies++; > } else { > + Efi_OldTPL = bs->RaiseTPL( TPL_CALLBACK); > bs->RestoreTPL ( efi_external_tpl ); > bs->RaiseTPL ( efi_internal_tpl ); > + if ( Efi_OldTPL != 0 ) { > + bs->RestoreTPL(Efi_OldTPL); > + } > + > } > > return ( efi_jiffies * ( TICKS_PER_SEC / EFI_JIFFIES_PER_SEC ) ); > -- > 2.35.1 >
Context for submitting that patch is https://github.com/ipxe/ipxe/issues/349#issuecomment-1126793404 that comment says This commit was part of the pull request #113. That pull request was never merged, because, as far as i understand, the root issue seemed to have been fixed with pull request #120 which was merged. The problem we are seeing however is still exactly the one that was discussed in #113 and #120 did not fix the problem entirely. Spamfilter did probably what they can do: Dropping emails. Here the patch twice. Once inline, probably mangled intransit, the other one attached, hopefully untouched. >From: He He4 Huang <huang...@lenovo.com> Date: Sat, 14 May 2022 21:57:41 +0200 Subject: [PATCH] [efi] Restore the TPL to the original one iPXE added a workaround to raise TPL to TPL_CALLBACK always, but it would cause UEFI firmware exit boot service callback with the same TPL level cannot be executed. Worse, some UEFI modules set a pointer at exit boot service callback and use later, then will encounter exception / hang for invalid pointer which is not set to a correct one since the exit boot service callback is not executed. The solution is to restore the TPL to the original one but not always set it to TPL_CALLBACK. --- src/interface/efi/efi_timer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/interface/efi/efi_timer.c b/src/interface/efi/efi_timer.c index 6427eb1d..24c506fc 100644 --- a/src/interface/efi/efi_timer.c +++ b/src/interface/efi/efi_timer.c @@ -133,11 +133,18 @@ static unsigned long efi_currticks ( void ) { * EFI's violation of this assumption by falling back to a * simple free-running monotonic counter during shutdown. */ + EFI_TPL Efi_OldTPL; + Efi_OldTPL=0; if ( efi_shutdown_in_progress ) { efi_jiffies++; } else { + Efi_OldTPL = bs->RaiseTPL( TPL_CALLBACK); bs->RestoreTPL ( efi_external_tpl ); bs->RaiseTPL ( efi_internal_tpl ); + if ( Efi_OldTPL != 0 ) { + bs->RestoreTPL(Efi_OldTPL); + } + } return ( efi_jiffies * ( TICKS_PER_SEC / EFI_JIFFIES_PER_SEC ) ); -- 2.35.1 Groeten Geert Stappers -- Silence is hard to parse
>From 39e1be240ba399678e070be3aac6694862238bb9 Mon Sep 17 00:00:00 2001 From: He He4 Huang <huang...@lenovo.com> Date: Sat, 14 May 2022 21:57:41 +0200 Subject: [PATCH] [efi] Restore the TPL to the original one iPXE added a workaround to raise TPL to TPL_CALLBACK always, but it would cause UEFI firmware exit boot service callback with the same TPL level cannot be executed. Worse, some UEFI modules set a pointer at exit boot service callback and use later, then will encounter exception / hang for invalid pointer which is not set to a correct one since the exit boot service callback is not executed. The solution is to restore the TPL to the original one but not always set it to TPL_CALLBACK. --- src/interface/efi/efi_timer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/interface/efi/efi_timer.c b/src/interface/efi/efi_timer.c index 6427eb1d..24c506fc 100644 --- a/src/interface/efi/efi_timer.c +++ b/src/interface/efi/efi_timer.c @@ -133,11 +133,18 @@ static unsigned long efi_currticks ( void ) { * EFI's violation of this assumption by falling back to a * simple free-running monotonic counter during shutdown. */ + EFI_TPL Efi_OldTPL; + Efi_OldTPL=0; if ( efi_shutdown_in_progress ) { efi_jiffies++; } else { + Efi_OldTPL = bs->RaiseTPL( TPL_CALLBACK); bs->RestoreTPL ( efi_external_tpl ); bs->RaiseTPL ( efi_internal_tpl ); + if ( Efi_OldTPL != 0 ) { + bs->RestoreTPL(Efi_OldTPL); + } + } return ( efi_jiffies * ( TICKS_PER_SEC / EFI_JIFFIES_PER_SEC ) ); -- 2.35.1
_______________________________________________ ipxe-devel mailing list ipxe-devel@lists.ipxe.org https://lists.ipxe.org/mailman/listinfo/ipxe-devel