Re: [edk2] [RFC 00/15] S3 suspend/resume for OVMF (WIP)

Subject: Re: [edk2] [RFC 00/15] S3 suspend/resume for OVMF (WIP)

From: Laszlo Ersek <>


Date: 2013-12-04 00:07:35

On 12/02/13 18:04, Laszlo Ersek wrote:

> The big problem is that nothing ever installs
> EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL. As a consequence, the boot script is
> never saved (not even an empty one), *and* BootScriptExecutorDxe never
> copies itself to reserved memory (in order to survive the suspension).
> Symptoms are:
> - the "SMM IPL!  DXE SMM Ready To Lock Protocol not installed before
>   Ready To Boot signal" warning when I boot a boot option,
> - when I try to resume, the third RestoreLockBox() call in
>   S3RestoreConfig2() fails, and the next assertion fails:
>   VarSize   = sizeof (EFI_PHYSICAL_ADDRESS);
>   Status = RestoreLockBox (
>              &gEfiBootScriptExecutorVariableGuid,
>              &TempEfiBootScriptExecutorVariable,
>              &VarSize
>              );
>   ASSERT_EFI_ERROR (Status);
> Of course I can install/emit EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL myself.
> I just don't know *when* to install it.
> As I wrote in the commit messages below, BdsLibBootViaBootOption() calls
> into EFI_ACPI_S3_SAVE_PROTOCOL [AcpiS3SaveDxe], and it needs SMRAM
> access. So, I can't install DXE_SMM_READY_TO_LOCK earlier than that.
> OTOH, I don't have control over any code that runs *after* it.
> Maybe I could install DXE_SMM_READY_TO_LOCK from a ready-to-boot event
> handler, but the SMM core & drivers already seem to install a bunch of
> stuff on that event, and I'm not sure the ordering between the handlers
> would be correct.

In patch 07/15 I created a customized copy of AcpiS3SaveDxe anyway, so I
just patched the S3Ready() function in a new patch (inserted between 09
and 10. The last step of S3Ready() is now to prepare the boot script at
once, and install DXE_SMM_READY_TO_LOCK too.

This way everything is prepared and saved in correct order, and the call
in BdsLibBootViaBootOption() is what triggers the whole thing.

After resume, the boot script executor runs the script (yay!), but I ran
into other trouble.  After a point S3Resume.c starts calling functions
by switching stacks explicitly (and such functions can't return
normally, they have to switch back, to an address they take as parameter):

S3RestoreConfig2() -- main function of the PEIM
    S3BootScriptExecutorEntryFunction() -- called via stack switching

Before S3ResumeExecuteBootScript() calls
S3BootScriptExecutorEntryFunction() via stack switching, it describes
the function the latter has to "return" (actually, jump) to. The target
function is S3ResumeBootOs() (which would jump to the OS wakeup vector
in the FACS):

S3RestoreConfig2() -- main function of the PEIM
    S3BootScriptExecutorEntryFunction() -- called via stack switching
    S3ResumeBootOs() -- jumped-to via stach switching
      jump to vector in FACS

S3BootScriptExecutorEntryFunction() indeed runs (it interprets the boot
script), and wants to jump to S3ResumeBootOs(). However, the stack that
S3ResumeExecuteBootScript() has prepared for it is wrong:

  PeiS3ResumeState->ReturnStackPointer =

"Status" is the first local variable in S3ResumeExecuteBootScript().
Presumably, S3ResumeExecuteBootScript() wants
S3BootScriptExecutorEntryFunction() to restore the original stack.

This doesn't work however, because gcc juggles the layout of
auto-variables on the stack freely, and in this case "Status" ends up at
an address that is not a multiple of CPU_STACK_ALIGNMENT. Hence
SwitchStack() ASSERT()s.

I'm fixing this with another patch -- instead of relying on the layout
of local variables and calling convention, I use a statically (or maybe
dynamically) allocated array as stack.

S3ResumeBootOs() is reached in fact and seems to call the FACS vector,
but now I'm getting an infinite reboot loop... :)


Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
edk2-devel mailing list