From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from a7-12.smtp-out.eu-west-1.amazonses.com (a7-12.smtp-out.eu-west-1.amazonses.com [54.240.7.12]) by mx.groups.io with SMTP id smtpd.web10.9968.1670581220528186788 for ; Fri, 09 Dec 2022 02:20:20 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@ipxe.org header.s=cphpx6z2rfcgehlykjjh3gknqe3hsoe2 header.b=JqxoYBhq; spf=pass (domain: eu-west-1.amazonses.com, ip: 54.240.7.12, mailfrom: 01020184f6666d2f-ac1beed5-7683-4209-bf13-282fc0ca754f-000000@eu-west-1.amazonses.com) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=cphpx6z2rfcgehlykjjh3gknqe3hsoe2; d=ipxe.org; t=1670581218; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Transfer-Encoding; bh=hLq25UAsoDsVSvML+sT1DkE306K8hxf52WU3OsRrqrA=; b=JqxoYBhqi5FIA+ogpx3hHge+IG1IlBVVDl33+pN6LqLpiFq0lIUoe6jmv+DdD8XO RbqRvymRLC/0ywrdbs43oVTJZCUFwJbZ36kE1DEbw4Azi2NdXaDVBU0DFTi1pjDjUvy 3oUfk461U3F81K8u7+n8KKFP1eMpLoNw5byggFPZlDwu/Cj24fU8L74K0kKeSiWUGyr 0vLW1moxuFSNekgKTcscVEvm6x+4Yh5gIYQ62jjdrSbiBZTMlEp95LanugP+s0FQP/G LbATSTIhlJkRVyPohumm1S6sQf20hAHq4jwbh1DHvDdN/QvIHCdrNdDtN9xBZTAEDCQ SuJspfKKCQ== DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=ihchhvubuqgjsxyuhssfvqohv7z3u4hn; d=amazonses.com; t=1670581218; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Transfer-Encoding:Feedback-ID; bh=hLq25UAsoDsVSvML+sT1DkE306K8hxf52WU3OsRrqrA=; b=DOZ5XMM1q2ZTFF1TbMc8kk1QLXiYBXsmJVun0hrRhgFL1Ajmx/xIPNrIa0r6wdXa unv6O1WXisIttPpB/13s7vzF/Zi8KFVUPnaMVOCsnHKoHBlW7r6+RnLiMccfhSxXoNw bN0Rj8dj7sEvE3jELM7mvjUjwJneNjxvKJFtV7qM= From: "Michael Brown" To: devel@edk2.groups.io Cc: Michael Brown , Laszlo Ersek , Paolo Bonzini Subject: [PATCH 0/3] OvmfPkg: Fix handling of nested interrupts Date: Fri, 9 Dec 2022 10:20:18 +0000 Message-ID: <01020184f6666d2f-ac1beed5-7683-4209-bf13-282fc0ca754f-000000@eu-west-1.amazonses.com> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, URIBL_DBL_BLOCKED_OPENDNS,URIBL_ZEN_BLOCKED_OPENDNS autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on blyat.fensystems.co.uk Feedback-ID: 1.eu-west-1.fspj4M/5bzJ9NLRzJP0PaxRwxrpZqiDQJ1IF94CF2TA=:AmazonSES X-SES-Outgoing: 2022.12.09-54.240.7.12 Content-Transfer-Encoding: 8bit Commit 239b50a86 ("OvmfPkg: End timer interrupt later to avoid stack overflow under load") deferred the call to SendApicEoi() until after the call to RestoreTPL(), in order to avoid the potential stack underflow as described in bug 2815. This has the unwanted side effect that any callbacks invoked as a result of RestoreTPL() will now run before the EOI is sent to the APIC. Until the callbacks return, no further timer interrupts will be raised and the system time value in mEfiSystemTime will remain unchanging. If any callbacks invoked by RestoreTPL() include a timeout loop based on mEfiSystemTime (e.g. via SetTimer() and CheckEvent()), this loop will never time out and the system will appear to hang. This situation can be reproduced by e.g. attaching a USB network card connected via an xHCI USB controller. The "system poll timer" callback to MnpSystemPoll() will eventually cause the following sequence of events: - Hardware timer interrupt occurs - TimerInterruptHandler() in LocalApicTimerDxe is called - TimerInterruptHandler() calls RaiseTPL(TPL_HIGH_LEVEL) - TimerInterruptHandler() calls RestoreTPL() before sending EOI - RestoreTPL() triggers a call to MnpSystemPoll() - MnpSystemPoll() ends up calling through to XhcExecTransfer() to poll the USB device - XhcExecTransfer() enters a loop waiting for the transfer to complete or time out - XhcExecTransfer() uses CheckEvent() to check for the timeout condition - Since EOI has not been sent, no further timer interrupts will occur and so CheckEvent() always returns EFI_NOT_READY and XhcExecTransfer() waits indefinitely in its timeout loop - User sees a totally stuck system that is unresponsive to any input other than a hard reset This patch series reverts commit 239b50a86 ("OvmfPkg: End timer interrupt later to avoid stack overflow under load") and introduces instead a new abstraction NestedInterruptTplLib to handle the intricacies required to safely allow nested interrupts without changing the core UEFI abstractions for RaiseTPL() and RestoreTPL(). The NestedInterruptTplLib could in principle be used by all timer interrupt handlers including those used on physical hardware platforms. Doing so would allow those platforms to provide a guarantee against interrupt-induced stack underflow. To simplify the EDK2 review process, the current patch series modifies only platforms within OvmfPkg, since those are the only platforms currently suffering from the regression. Cc: Laszlo Ersek Cc: Paolo Bonzini Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2815 Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4162 Michael Brown (3): OvmfPkg: Send EOI before RestoreTPL() in timer interrupt handlers OvmfPkg: Add library to handle TPL from within nested interrupt handlers OvmfPkg: Use NestedInterruptTplLib in nested interrupt handlers OvmfPkg/8254TimerDxe/8254Timer.inf | 1 + OvmfPkg/8254TimerDxe/Timer.c | 14 +- OvmfPkg/AmdSev/AmdSevX64.dsc | 1 + OvmfPkg/CloudHv/CloudHvX64.dsc | 1 + .../Include/Library/NestedInterruptTplLib.h | 87 +++++++ OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 + OvmfPkg/Library/NestedInterruptTplLib/Iret.c | 62 +++++ OvmfPkg/Library/NestedInterruptTplLib/Iret.h | 19 ++ .../NestedInterruptTplLib.inf | 35 +++ OvmfPkg/Library/NestedInterruptTplLib/Tpl.c | 216 ++++++++++++++++++ OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.c | 14 +- .../LocalApicTimerDxe/LocalApicTimerDxe.inf | 1 + OvmfPkg/Microvm/MicrovmX64.dsc | 1 + OvmfPkg/OvmfPkg.dec | 4 + OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/OvmfXen.dsc | 1 + 18 files changed, 449 insertions(+), 12 deletions(-) create mode 100644 OvmfPkg/Include/Library/NestedInterruptTplLib.h create mode 100644 OvmfPkg/Library/NestedInterruptTplLib/Iret.c create mode 100644 OvmfPkg/Library/NestedInterruptTplLib/Iret.h create mode 100644 OvmfPkg/Library/NestedInterruptTplLib/NestedInterruptTplLib.inf create mode 100644 OvmfPkg/Library/NestedInterruptTplLib/Tpl.c -- 2.38.1