f53835584a
- edk2-OvmfPkg-Clarify-invariants-for-NestedInterruptTplLib.patch [bz#2189136] - edk2-OvmfPkg-Relax-assertion-that-interrupts-do-not-occur.patch [bz#2189136] - Resolves: bz#2189136 (windows 11 installation broken with edk2-20230301gitf80f052277c8-1.el9)
82 lines
3.4 KiB
Diff
82 lines
3.4 KiB
Diff
From 28c2cf5f8fa5021ff3a6b83fe07dc519084143c0 Mon Sep 17 00:00:00 2001
|
|
From: Michael Brown <mcb30@ipxe.org>
|
|
Date: Tue, 9 May 2023 12:09:33 +0000
|
|
Subject: [PATCH 2/2] OvmfPkg: Relax assertion that interrupts do not occur at
|
|
TPL_HIGH_LEVEL
|
|
|
|
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
|
RH-MergeRequest: 35: OvmfPkg: backport NestedInterruptTplLib updates
|
|
RH-Bugzilla: 2189136
|
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
RH-Commit: [2/2] ffb3cf6132b774295a49d16d4ef35164b61c0de3 (kraxel/centos-edk2)
|
|
|
|
At TPL_HIGH_LEVEL, CPU interrupts are disabled (as per the UEFI
|
|
specification) and so we should never encounter a situation in which
|
|
an interrupt occurs at TPL_HIGH_LEVEL. The specification also
|
|
restricts usage of TPL_HIGH_LEVEL to the firmware itself.
|
|
|
|
However, nothing actually prevents a UEFI application from calling
|
|
gBS->RaiseTPL(TPL_HIGH_LEVEL) and then violating the invariant by
|
|
enabling interrupts via the STI or equivalent instruction. Some
|
|
versions of the Microsoft Windows bootloader are known to do this.
|
|
|
|
NestedInterruptTplLib maintains the invariant that interrupts are
|
|
disabled at TPL_HIGH_LEVEL (even when performing the dark art of
|
|
deliberately manipulating the stack so that IRET will return with
|
|
interrupts still disabled), but does not itself rely on external code
|
|
maintaining this invariant.
|
|
|
|
Relax the assertion that the interrupted TPL is below TPL_HIGH_LEVEL
|
|
to an error message, to allow UEFI applications such as these versions
|
|
of the Microsoft Windows bootloader to continue to function.
|
|
|
|
Debugged-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
Debugged-by: Laszlo Ersek <lersek@redhat.com>
|
|
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=2189136
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
(cherry picked from commit bee67e0c142af6599a85aa7640094816b8a24c4f)
|
|
---
|
|
OvmfPkg/Library/NestedInterruptTplLib/Tpl.c | 21 ++++++++++++++++++---
|
|
1 file changed, 18 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c b/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
|
index e921a09c55..d56c12a445 100644
|
|
--- a/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
|
+++ b/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
|
@@ -34,12 +34,27 @@ NestedInterruptRaiseTPL (
|
|
|
|
//
|
|
// Raise TPL and assert that we were called from within an interrupt
|
|
- // handler (i.e. with TPL below TPL_HIGH_LEVEL but with interrupts
|
|
- // disabled).
|
|
+ // handler (i.e. with interrupts already disabled before raising the
|
|
+ // TPL).
|
|
//
|
|
ASSERT (GetInterruptState () == FALSE);
|
|
InterruptedTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
|
- ASSERT (InterruptedTPL < TPL_HIGH_LEVEL);
|
|
+
|
|
+ //
|
|
+ // At TPL_HIGH_LEVEL, CPU interrupts are disabled (as per the UEFI
|
|
+ // specification) and so we should never encounter a situation in
|
|
+ // which InterruptedTPL==TPL_HIGH_LEVEL. The specification also
|
|
+ // restricts usage of TPL_HIGH_LEVEL to the firmware itself.
|
|
+ //
|
|
+ // However, nothing actually prevents a UEFI application from
|
|
+ // invalidly calling gBS->RaiseTPL(TPL_HIGH_LEVEL) and then
|
|
+ // violating the invariant by enabling interrupts via the STI or
|
|
+ // equivalent instruction. Some versions of the Microsoft Windows
|
|
+ // bootloader are known to do this.
|
|
+ //
|
|
+ if (InterruptedTPL >= TPL_HIGH_LEVEL) {
|
|
+ DEBUG ((DEBUG_ERROR, "ERROR: Interrupts enabled at TPL_HIGH_LEVEL!\n"));
|
|
+ }
|
|
|
|
return InterruptedTPL;
|
|
}
|
|
--
|
|
2.39.1
|
|
|