update NestedInterruptTplLib patches
This commit is contained in:
parent
82b6b6aa9f
commit
9839d74e46
@ -0,0 +1,66 @@
|
|||||||
|
From 51846ff74e3352151f99cfcfbe091c09f3ec8097 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Brown <mcb30@ipxe.org>
|
||||||
|
Date: Tue, 9 May 2023 12:09:30 +0000
|
||||||
|
Subject: [PATCH 16/18] OvmfPkg: Clarify invariants for NestedInterruptTplLib
|
||||||
|
|
||||||
|
NestedInterruptTplLib relies on CPU interrupts being disabled to
|
||||||
|
guarantee exclusive (and hence atomic) access to the shared state in
|
||||||
|
IsrState. Nothing in the calling interrupt handler should have
|
||||||
|
re-enabled interrupts before calling NestedInterruptRestoreTPL(), and
|
||||||
|
the loop in NestedInterruptRestoreTPL() itself maintains the invariant
|
||||||
|
that interrupts are disabled at the start of each iteration.
|
||||||
|
|
||||||
|
Add assertions to clarify this invariant, and expand the comments
|
||||||
|
around the calls to RestoreTPL() and DisableInterrupts() to clarify
|
||||||
|
the expectations around enabling and disabling interrupts.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
||||||
|
Acked-by: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
(cherry picked from commit ae0be176a83efebe9a8c13d2124151f7dd13443a)
|
||||||
|
---
|
||||||
|
OvmfPkg/Library/NestedInterruptTplLib/Tpl.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c b/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
||||||
|
index e19d98878eb7..e921a09c5599 100644
|
||||||
|
--- a/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
||||||
|
+++ b/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
||||||
|
@@ -104,6 +104,7 @@ NestedInterruptRestoreTPL (
|
||||||
|
// defer our call to RestoreTPL() to the in-progress outer instance
|
||||||
|
// of the same interrupt handler.
|
||||||
|
//
|
||||||
|
+ ASSERT (GetInterruptState () == FALSE);
|
||||||
|
if (InterruptedTPL == IsrState->InProgressRestoreTPL) {
|
||||||
|
//
|
||||||
|
// Trigger outer instance of this interrupt handler to perform the
|
||||||
|
@@ -153,6 +154,7 @@ NestedInterruptRestoreTPL (
|
||||||
|
//
|
||||||
|
// Check shared state loop invariants.
|
||||||
|
//
|
||||||
|
+ ASSERT (GetInterruptState () == FALSE);
|
||||||
|
ASSERT (IsrState->InProgressRestoreTPL < InterruptedTPL);
|
||||||
|
ASSERT (IsrState->DeferredRestoreTPL == FALSE);
|
||||||
|
|
||||||
|
@@ -167,13 +169,17 @@ NestedInterruptRestoreTPL (
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call RestoreTPL() to allow event notifications to be
|
||||||
|
- // dispatched. This will implicitly re-enable interrupts.
|
||||||
|
+ // dispatched. This will implicitly re-enable interrupts (if
|
||||||
|
+ // InterruptedTPL is below TPL_HIGH_LEVEL), even though we are
|
||||||
|
+ // still inside the interrupt handler.
|
||||||
|
//
|
||||||
|
gBS->RestoreTPL (InterruptedTPL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Re-disable interrupts after the call to RestoreTPL() to ensure
|
||||||
|
- // that we have exclusive access to the shared state.
|
||||||
|
+ // that we have exclusive access to the shared state. Interrupts
|
||||||
|
+ // will be re-enabled by the IRET or equivalent instruction when
|
||||||
|
+ // we subsequently return from the interrupt handler.
|
||||||
|
//
|
||||||
|
DisableInterrupts ();
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
From 7c65395d2b45e388c6c106cb619ab93c2359f5e4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
|
||||||
Date: Thu, 27 Apr 2023 12:14:16 +0200
|
|
||||||
Subject: [PATCH 16/17] OvmfPkg/NestedInterruptTplLib: replace ASSERT() with a
|
|
||||||
warning logged.
|
|
||||||
|
|
||||||
OVMF can't guarantee that the ASSERT() doesn't happen. Misbehaving
|
|
||||||
EFI applications can trigger this. So log a warning instead and try
|
|
||||||
to continue.
|
|
||||||
|
|
||||||
Reproducer: Fetch windows 11 22H2 iso image, boot it in qemu with OVMF.
|
|
||||||
|
|
||||||
Traced to BootServices->Stall() being called with IPL=TPL_HIGH_LEVEL
|
|
||||||
and Interrupts /enabled/ while windows is booting.
|
|
||||||
|
|
||||||
Cc: Michael Brown <mcb30@ipxe.org>
|
|
||||||
Cc: Laszlo Ersek <lersek@redhat.com>
|
|
||||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
||||||
---
|
|
||||||
OvmfPkg/Library/NestedInterruptTplLib/Tpl.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c b/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
|
||||||
index e19d98878eb7..fdd7d15c4ba8 100644
|
|
||||||
--- a/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
|
||||||
+++ b/OvmfPkg/Library/NestedInterruptTplLib/Tpl.c
|
|
||||||
@@ -39,7 +39,9 @@ NestedInterruptRaiseTPL (
|
|
||||||
//
|
|
||||||
ASSERT (GetInterruptState () == FALSE);
|
|
||||||
InterruptedTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
|
||||||
- ASSERT (InterruptedTPL < TPL_HIGH_LEVEL);
|
|
||||||
+ if (InterruptedTPL >= TPL_HIGH_LEVEL) {
|
|
||||||
+ DEBUG ((DEBUG_WARN, "%a: Called at IPL %d\n", __func__, InterruptedTPL));
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return InterruptedTPL;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.40.1
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
|||||||
|
From 7272c2fbe66941f0785be7ec437ed79ab9e35b80 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Brown <mcb30@ipxe.org>
|
||||||
|
Date: Tue, 9 May 2023 12:09:33 +0000
|
||||||
|
Subject: [PATCH 17/18] OvmfPkg: Relax assertion that interrupts do not occur
|
||||||
|
at 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
|
||||||
|
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 e921a09c5599..d56c12a44529 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.40.1
|
||||||
|
|
@ -98,7 +98,8 @@ Patch0012: 0012-OvmfPkg-QemuKernelLoaderFsDxe-suppress-error-on-no-k.patch
|
|||||||
Patch0013: 0013-SecurityPkg-Tcg2Dxe-suppress-error-on-no-swtpm-in-si.patch
|
Patch0013: 0013-SecurityPkg-Tcg2Dxe-suppress-error-on-no-swtpm-in-si.patch
|
||||||
Patch0014: 0014-SecurityPkg-add-TIS-sanity-check-tpm2.patch
|
Patch0014: 0014-SecurityPkg-add-TIS-sanity-check-tpm2.patch
|
||||||
Patch0015: 0015-SecurityPkg-add-TIS-sanity-check-tpm12.patch
|
Patch0015: 0015-SecurityPkg-add-TIS-sanity-check-tpm12.patch
|
||||||
Patch0016: 0016-OvmfPkg-NestedInterruptTplLib-replace-ASSERT-with-a-.patch
|
Patch0016: 0016-OvmfPkg-Clarify-invariants-for-NestedInterruptTplLib.patch
|
||||||
|
Patch0017: 0017-OvmfPkg-Relax-assertion-that-interrupts-do-not-occur.patch
|
||||||
|
|
||||||
|
|
||||||
# python3-devel and libuuid-devel are required for building tools.
|
# python3-devel and libuuid-devel are required for building tools.
|
||||||
|
Loading…
Reference in New Issue
Block a user