> -----Original Message-----
> From: Paolo Bonzini <pbonz...@redhat.com>
> Sent: Thursday, February 29, 2024 11:04 AM
> To: Ni, Ray <ray...@intel.com>; devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Liming Gao
> <gaolim...@byosoft.com.cn>; Laszlo Ersek <ler...@redhat.com>; Michael
> Brown <mc...@ipxe.org>
> Subject: Re: [PATCH 2/2] MdeModulePkg/DxeCore: Fix stack overflow issue
> due to nested interrupts
> 
> 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 ?

Yes.  This same issue can be reproduced on non-OVMF platforms.

This proposal here is an attempt to integrate a common fix into the DXE Core.

I would agree conceptually that integrating the NestedInterruptTplLib work
into the DXE Core is another option.

I believe the root cause of all of these scenarios is enabling interrupts
in RestoreTPL() when processing a timer interrupt between the last processed
event and the return from the interrupt handler. Ther are some instances
of the Timer Arch Protocol implementation that call Raise/Restore TPL, so
we want a DXE Core change that is compatible with the DXE Core doing 
Raise/Restore
when processing a timer interrupt and the Timer Arch Protocol implementation
also doing the Raise/Restore TPL.

> 
> 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 (#116184): https://edk2.groups.io/g/devel/message/116184
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