On Fri, Mar 1, 2024 at 4:08 AM Ni, Ray wrote: > @@ -161,5 +191,46 @@ CoreRestoreTpl ( > IN EFI_TPL NewTpl > ) > { > + BOOLEAN InInterruptHandler = FALSE; > + > + // > + // Unwind the nested interrupt handlers up to the required > + // TPL, paying attention not to overflow the stack. While > + // not strictly necessary according to the specification, > + // accept the possibility that multiple RaiseTPL calls are > + // undone by a single RestoreTPL > + // > + while ((INTN)NewTpl <= HighBitSet64 (mInterruptedTplMask)) { > 1. why "<="? I thought when RestoreTPL() is called there are only two cases: > a. NewTpl == HighBitSet64 (...) > b. NewTpl > HighBitSet64 (...) > 1.a is the case when TimerInterruptHandler() or CoreTimerTick() restores > TPL from HIGH to non-HIGH. > 1.b is the case when the pending event backs call RaiseTPL/RestoreTPL(). > Because only pending events whose TPL > "Interrupted TPL" can run, the > RestoreTPL() call from the event callbacks cannot change the TPL to a value > less than or equal to "Interrupted TPL". > So, I think "<=" can be "==". > > 2. can you explain a bit more about the reason of "while"? Both are just for extra safety. The required invariant is that all bits at or below current TPL are cleared, and using "while (... <= ...)" makes it more robust to incorrect usage of gBS->RestoreTPL(). Indeed, the patch at the top of thread also uses "(INTN)gEfiCurrentTpl > HighBitSet64 (mInterruptedTplMask)", which is <= when you reverse the condition. It then asserts inside the conditional that "==" would be enough. So I am starting to see more and more similarities between the two approaches. I went a step further with fresh mind, removing the while loop... and basically reinvented your and Michael's patch. :) The only difference in the logic is a slightly different handling of mInterruptedTplMask in CoreRestoreTpl(), which is a bit safer in my case. However, my roundabout way of getting to the same patch resulted in very different comments. Personally, I found the large text at the head of mInterruptedTplMask a bit too much, and the ones inside the function too focused on "how" and not "why". Maybe it's my exposure to NestedInterruptTplLib, but I find that a much smaller text can achieve the same purpose, by explaining the logic instead of the individual steps. My version is attached, feel free to reuse it (either entirely or partially) for a hypothetical v2. Apologies to you and Mike K for the confusion! > + > + if (InterruptedTpl == NewTpl) { > + break; > 3. "break" or "return"? I think we should exit from this function. Indeed, this should have been a return. Paolo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116224): https://edk2.groups.io/g/devel/message/116224 Mute This Topic: https://groups.io/mt/104642317/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-