[pxe] Treat PXENV_RESTART_TFTP as unreturnable
authorMichael Brown <mcb30@ipxe.org>
Fri, 21 May 2010 02:10:03 +0000 (03:10 +0100)
committerStefan Hajnoczi <stefanha@gmail.com>
Wed, 7 Jul 2010 19:14:37 +0000 (20:14 +0100)
Microsoft WDS can end up calling PXENV_RESTART_TFTP to execute a
second-stage NBP which then exits.  Specifically, wdsnbp.com uses
PXENV_RESTART_TFTP to execute pxeboot.com, which will exit if the user
does not press F12.  gPXE currently treats PXENV_RESTART_TFTP as a
normal PXE API call, and so attempts to return to wdsnbp.com, which
has just been vaporised by pxeboot.com.

Use rmsetjmp/rmlongjmp to preserve the stack state as of the initial
NBP execution, and to restore this state immediately prior to
executing the NBP loaded via PXENV_RESTART_TFTP.  This matches the
behaviour in the PXE spec (which says that "if TFTP is restarted,
control is never returned to the caller"), and allows pxeboot.com to
exit relatively cleanly back to gPXE.

As with all usage of setjmp/longjmp, there may be subtle corner case
bugs due to not gracefully unwinding any state accumulated by the time
of the longjmp call, but this seems to be the only viable way to
provide the specified behaviour.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>

No differences found