[efi] Work around temporal anomaly encountered during ExitBootServices()
authorMichael Brown <mcb30@ipxe.org>
Wed, 7 Dec 2016 13:41:06 +0000 (13:41 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 7 Dec 2016 13:46:37 +0000 (13:46 +0000)
commit5cf5ffea2874434ffdc64c3242f2c53ed7ec1d40
tree5347859587c18d490a65de4cd6fa6170557ae211
parente09331a4c6731b771c60f554f33cf0fdf5775124
[efi] Work around temporal anomaly encountered during ExitBootServices()

EFI provides no clean way for device drivers to shut down in
preparation for handover to a booted operating system.  The platform
firmware simply doesn't bother to call the drivers' Stop() methods.
Instead, drivers must register an EVT_SIGNAL_EXIT_BOOT_SERVICES event
to be signalled when ExitBootServices() is called, and clean up
without any reference to the EFI driver model.

Unfortunately, all timers silently stop working when ExitBootServices()
is called.  Even more unfortunately, and for no discernible reason,
this happens before any EVT_SIGNAL_EXIT_BOOT_SERVICES events are
signalled.  The net effect of this entertaining design choice is that
any timeout loops on the shutdown path (e.g. for gracefully closing
outstanding TCP connections) may wait indefinitely.

There is no way to report failure from currticks(), since the API
lazily assumes that the host system continues to travel through time
in the usual direction.  Work around EFI's violation of this
assumption by falling back to a simple free-running monotonic counter.

Debugged-by: Maor Dickman <maord@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi.h
src/interface/efi/efi_init.c
src/interface/efi/efi_timer.c