[ipxe-devel] [ipxe/ipxe] [efi] Restore the TPL to the original one (#113)

Michael Brown notifications at github.com
Tue Jun 30 11:00:27 UTC 2020


@huanghe4 The expected mechanism (as documented in [[efi] Run at TPL_CALLBACK to protect against UEFI timers](https://github.com/ipxe/ipxe/commit/c89a446cf09f30a121ae21d91f4a1aa071044084#diff-8abaf825db412e28b0c57b0f8947ed23) is that iPXE code runs at TPL_CALLBACK almost all of the time, in order to overcome fundamental design flaws in the UEFI specification.

iPXE will record the TPL at which it was entered and will restore this TPL before exiting.  This applies to all externally callable entry points, such as the SNP API (see e.g. the matched RaiseTPL/RestoreTPL calls in `efi_snp_get_status()`).

This also applies to the overall code path from initial invocation through to ExitBootServices, although this is less immediately obvious due to the exchange of responsibilities between different UEFI components.  The expected sequence of events is:
* An application-level entry point such as `_efi_start()` or `efi_snp_load_file()` (as opposed to an API-level entry point such as `efi_snp_get_status()`) will call `efi_snp_claim()` to claim exclusive ownership of the network devices for iPXE (and so to prevent packet loss due to other UEFI code attempting to poll the network).
* This call to `efi_snp_claim()` will record the original TPL in `efi_snp_old_tpl` and will raise to TPL_CALLBACK.
* Before executing an image (such as an OS kernel), iPXE will call `efi_snp_release()`
* This call to `efi_snp_release()` will restore the original TPL as recorded in `efi_snp_old_tpl`
* iPXE then invokes the OS kernel via `StartImage()`.  At this point, the TPL is whatever TPL was recorded when iPXE was started, which should be TPL_APPLICATION.
* The OS kernel is responsible for calling `ExitBootServices()`

I have added debug code to iPXE to dump the TPL prior to calling `StartImage()` and (via the `efi_wrap` mechanism) to dump the TPL at the point that the OS kernel invokes `ExitBootServices()`.  I have tested with both an iPXE EFI ROM and with a chainloaded `snponly.efi`.  In both cases and at both debug points the TPL was TPL_APPLICATION, as expected.

Is it possible that the AMI BIOS is erroneously starting iPXE at TPL_CALLBACK, thereby causing `efi_snp_old_tpl` to end up containing TPL_CALLBACK rather than TPL_APPLICATION?

Michael


-- 
You are receiving this because you commented.
Reply to this email directly or view it on GitHub:
https://github.com/ipxe/ipxe/pull/113#issuecomment-651721586
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ipxe.org/pipermail/ipxe-devel/attachments/20200630/2bdb5447/attachment.htm>


More information about the ipxe-devel mailing list