On 2/29/24 14:02, Ray Ni wrote:
In the end, it will lower the TPL to TPL_APPLICATION with interrupt enabled.

However, it's possible that another timer interrupt happens just in the end
of RestoreTPL() function when TPL is TPL_APPLICATION.

How do non-OVMF platforms solve the issue? Do they just have the same bug as in https://bugzilla.tianocore.org/show_bug.cgi?id=4162 ?

The design of NestedInterruptTplLib is that each nested interrupt must increase the TPL, but if I understand correctly there is a hole here:

  //
  // Call RestoreTPL() to allow event notifications to be
  // dispatched.  This will implicitly re-enable interrupts.
  //
  gBS->RestoreTPL (InterruptedTPL);

  //
  // Re-disable interrupts after the call to RestoreTPL() to ensure
  // that we have exclusive access to the shared state.
  //
  DisableInterrupts ();

because gBS->RestoreTPL will unconditionally enable interrupts if InterruptedTPL < TPL_HIGH_LEVEL.


If possible, the easiest solution would be to merge NestedInterruptTplLib into Core DXE. This way, instead of calling gBS->RestoreTPL, NestedInterruptTplLib can call a custom version of CoreRestoreTpl that exits with interrupts disabled. That is, something like

VOID EFIAPI CoreRestoreTplInternal(IN EFI_TPL NewTpl,
                                   IN BOOLEAN InterruptState)
{
  //
  // The caller can request disabled interrupts to access shared
  // state, but TPL_HIGH_LEVEL must *not* have them enabled.
  //
  ASSERT(!(NewTpl == TPL_HIGH_LEVEL && InterruptState));

  // ...

  gEfiCurrentTpl = NewTpl;
  CoreSetInterruptState (InterruptState);
}

Now, CoreRestoreTpl is just

  //
  // If lowering below HIGH_LEVEL, make sure
  // interrupts are enabled
  //
  CoreRestoreTplInternal(NewTpl, NewTpl < TPL_HIGH_LEVEL);

whereas NestedInterruptRestoreTPL can do

  //
  // Call RestoreTPL() to allow event notifications to be
  // dispatched.  This will implicitly re-enable interrupts,
  // but only if events have to be dispatched.
  //
  CoreRestoreTplInternal(InterruptedTPL, FALSE);

  //
  // Interrupts are now disabled, so we can access shared state.
  //

This avoids the unlimited nesting of interrupts because each stack frame will indeed have a higher TPL than the outer version.

Paolo



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#116181): https://edk2.groups.io/g/devel/message/116181
Mute This Topic: https://groups.io/mt/104642317/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to