[ipxe-devel] [PATCH] [efi] Restore the TPL to the original one

Geert Stappers stappers at stappers.nl
Sat May 14 20:33:05 UTC 2022


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 <huanghe4 at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-efi-Restore-the-TPL-to-the-original-one.patch
Type: text/x-diff
Size: 1534 bytes
Desc: not available
URL: <http://lists.ipxe.org/pipermail/ipxe-devel/attachments/20220514/1d60e572/attachment.bin>


More information about the ipxe-devel mailing list