diff --git a/0017-OvmfPkg-IoMmuDxe-don-t-rely-on-TPLs-to-manage-concur.patch b/0017-OvmfPkg-IoMmuDxe-don-t-rely-on-TPLs-to-manage-concur.patch new file mode 100644 index 0000000..cded6bc --- /dev/null +++ b/0017-OvmfPkg-IoMmuDxe-don-t-rely-on-TPLs-to-manage-concur.patch @@ -0,0 +1,235 @@ +From bf2f6173802c709a84c36d43f414c815ad6aa2f6 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Thu, 20 Jul 2023 15:45:57 +0200 +Subject: [PATCH 17/20] OvmfPkg/IoMmuDxe: don't rely on TPLs to manage + concurrency + +Instead of relying on raising the TPL to protect the critical sections +that manipulate the global bitmask that keeps track of bounce buffer +allocations, use compare-and-exchange to manage the global variable, and +tweak the logic to line up with that. + +Given that IoMmuDxe implements a singleton protocol that is shared +between multiple drivers, and considering the elaborate and confusing +requirements in the UEFP spec regarding TPL levels at which protocol +methods may be invoked, not relying on TPL levels at all is a more +robust approach in this case. + +Link: https://bugzilla.redhat.com/show_bug.cgi?id=2211060 +Signed-off-by: Ard Biesheuvel +Acked-by: Pedro Falcato +(cherry picked from commit dfb941d32a2f38c9177729e39c6a6515abbbad48) +--- + OvmfPkg/IoMmuDxe/IoMmuDxe.inf | 1 + + OvmfPkg/IoMmuDxe/IoMmuBuffer.c | 100 +++++++++++++++++++-------------- + 2 files changed, 60 insertions(+), 41 deletions(-) + +diff --git a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf +index 17fca5285692..d08f7e59e2b6 100644 +--- a/OvmfPkg/IoMmuDxe/IoMmuDxe.inf ++++ b/OvmfPkg/IoMmuDxe/IoMmuDxe.inf +@@ -35,6 +35,7 @@ [LibraryClasses] + MemEncryptSevLib + MemEncryptTdxLib + MemoryAllocationLib ++ SynchronizationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +diff --git a/OvmfPkg/IoMmuDxe/IoMmuBuffer.c b/OvmfPkg/IoMmuDxe/IoMmuBuffer.c +index 103003cae376..f8dcd5b7ec92 100644 +--- a/OvmfPkg/IoMmuDxe/IoMmuBuffer.c ++++ b/OvmfPkg/IoMmuDxe/IoMmuBuffer.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include "IoMmuInternal.h" + +@@ -268,16 +269,17 @@ InternalAllocateBuffer ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, +- IN OUT UINT32 *ReservedMemBitmap, ++ OUT UINT32 *ReservedMemBit, + IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress + ) + { + UINT32 MemBitmap; ++ UINT32 ReservedMemBitmap; + UINT8 Index; + IOMMU_RESERVED_MEM_RANGE *MemRange; + UINTN PagesOfLastMemRange; + +- *ReservedMemBitmap = 0; ++ *ReservedMemBit = 0; + + if (Pages == 0) { + ASSERT (FALSE); +@@ -309,23 +311,31 @@ InternalAllocateBuffer ( + + MemRange = &mReservedMemRanges[Index]; + +- if ((mReservedMemBitmap & MemRange->BitmapMask) == MemRange->BitmapMask) { +- // The reserved memory is exausted. Turn to legacy allocate. +- goto LegacyAllocateBuffer; +- } ++ do { ++ ReservedMemBitmap = mReservedMemBitmap; + +- MemBitmap = (mReservedMemBitmap & MemRange->BitmapMask) >> MemRange->Shift; ++ if ((ReservedMemBitmap & MemRange->BitmapMask) == MemRange->BitmapMask) { ++ // The reserved memory is exhausted. Turn to legacy allocate. ++ goto LegacyAllocateBuffer; ++ } ++ ++ MemBitmap = (ReservedMemBitmap & MemRange->BitmapMask) >> MemRange->Shift; + +- for (Index = 0; Index < MemRange->Slots; Index++) { +- if ((MemBitmap & (UINT8)(1<Slots; Index++) { ++ if ((MemBitmap & (UINT8)(1<Slots); ++ ASSERT (Index != MemRange->Slots); + +- *PhysicalAddress = MemRange->StartAddressOfMemRange + Index * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize; +- *ReservedMemBitmap = (UINT32)(1 << (Index + MemRange->Shift)); ++ *PhysicalAddress = MemRange->StartAddressOfMemRange + Index * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize; ++ *ReservedMemBit = (UINT32)(1 << (Index + MemRange->Shift)); ++ } while (ReservedMemBitmap != InterlockedCompareExchange32 ( ++ &mReservedMemBitmap, ++ ReservedMemBitmap, ++ ReservedMemBitmap | *ReservedMemBit ++ )); + + DEBUG (( + DEBUG_VERBOSE, +@@ -334,16 +344,16 @@ InternalAllocateBuffer ( + MemRange->DataSize, + *PhysicalAddress, + Pages, +- *ReservedMemBitmap, +- mReservedMemBitmap, +- mReservedMemBitmap | *ReservedMemBitmap ++ *ReservedMemBit, ++ ReservedMemBitmap, ++ ReservedMemBitmap | *ReservedMemBit + )); + + return EFI_SUCCESS; + + LegacyAllocateBuffer: + +- *ReservedMemBitmap = 0; ++ *ReservedMemBit = 0; + return gBS->AllocatePages (Type, MemoryType, Pages, PhysicalAddress); + } + +@@ -366,27 +376,41 @@ IoMmuAllocateBounceBuffer ( + ) + { + EFI_STATUS Status; +- UINT32 ReservedMemBitmap; +- EFI_TPL OldTpl; +- +- OldTpl = gBS->RaiseTPL (TPL_NOTIFY); +- ReservedMemBitmap = 0; +- Status = InternalAllocateBuffer ( +- Type, +- MemoryType, +- MapInfo->NumberOfPages, +- &ReservedMemBitmap, +- &MapInfo->PlainTextAddress +- ); +- MapInfo->ReservedMemBitmap = ReservedMemBitmap; +- mReservedMemBitmap |= ReservedMemBitmap; +- gBS->RestoreTPL (OldTpl); + ++ Status = InternalAllocateBuffer ( ++ Type, ++ MemoryType, ++ MapInfo->NumberOfPages, ++ &MapInfo->ReservedMemBitmap, ++ &MapInfo->PlainTextAddress ++ ); + ASSERT (Status == EFI_SUCCESS); + + return Status; + } + ++/** ++ * Clear a bit in the reserved memory bitmap in a thread safe manner ++ * ++ * @param ReservedMemBit The bit to clear ++ */ ++STATIC ++VOID ++ClearReservedMemBit ( ++ IN UINT32 ReservedMemBit ++ ) ++{ ++ UINT32 ReservedMemBitmap; ++ ++ do { ++ ReservedMemBitmap = mReservedMemBitmap; ++ } while (ReservedMemBitmap != InterlockedCompareExchange32 ( ++ &mReservedMemBitmap, ++ ReservedMemBitmap, ++ ReservedMemBitmap & ~ReservedMemBit ++ )); ++} ++ + /** + * Free the bounce buffer allocated in IoMmuAllocateBounceBuffer. + * +@@ -398,8 +422,6 @@ IoMmuFreeBounceBuffer ( + IN OUT MAP_INFO *MapInfo + ) + { +- EFI_TPL OldTpl; +- + if (MapInfo->ReservedMemBitmap == 0) { + gBS->FreePages (MapInfo->PlainTextAddress, MapInfo->NumberOfPages); + } else { +@@ -412,11 +434,9 @@ IoMmuFreeBounceBuffer ( + mReservedMemBitmap, + mReservedMemBitmap & ((UINT32)(~MapInfo->ReservedMemBitmap)) + )); +- OldTpl = gBS->RaiseTPL (TPL_NOTIFY); ++ ClearReservedMemBit (MapInfo->ReservedMemBitmap); + MapInfo->PlainTextAddress = 0; +- mReservedMemBitmap &= (UINT32)(~MapInfo->ReservedMemBitmap); + MapInfo->ReservedMemBitmap = 0; +- gBS->RestoreTPL (OldTpl); + } + + return EFI_SUCCESS; +@@ -452,8 +472,6 @@ IoMmuAllocateCommonBuffer ( + ); + ASSERT (Status == EFI_SUCCESS); + +- mReservedMemBitmap |= *ReservedMemBitmap; +- + if (*ReservedMemBitmap != 0) { + *PhysicalAddress -= SIZE_4KB; + } +@@ -494,7 +512,7 @@ IoMmuFreeCommonBuffer ( + mReservedMemBitmap & ((UINT32)(~CommonBufferHeader->ReservedMemBitmap)) + )); + +- mReservedMemBitmap &= (UINT32)(~CommonBufferHeader->ReservedMemBitmap); ++ ClearReservedMemBit (CommonBufferHeader->ReservedMemBitmap); + return EFI_SUCCESS; + + LegacyFreeCommonBuffer: +-- +2.41.0 + diff --git a/0018-OvmfPkg-Disable-PcdFirstTimeWakeUpAPsBySipi.patch b/0018-OvmfPkg-Disable-PcdFirstTimeWakeUpAPsBySipi.patch new file mode 100644 index 0000000..cb9e3f8 --- /dev/null +++ b/0018-OvmfPkg-Disable-PcdFirstTimeWakeUpAPsBySipi.patch @@ -0,0 +1,84 @@ +From 2dd5afb5f43f645041b91c8fa6f797121a384061 Mon Sep 17 00:00:00 2001 +From: YuanhaoXie +Date: Tue, 22 Aug 2023 09:52:14 +0800 +Subject: [PATCH 18/20] OvmfPkg: Disable PcdFirstTimeWakeUpAPsBySipi + +Disable PcdFirstTimeWakeUpAPsBySipi for IntelTdx, Microvm, and Xen to +preserve the original execution of INIT-SIPI-SIPI. + +Cc: Eric Dong +Cc: Ray Ni +Cc: Rahul Kumar +Cc: Gerd Hoffmann +Cc: Ard Biesheuvel +Cc: Jiewen Yao +Cc: Jordan Justen +Signed-off-by: Yuanhao Xie +Acked-by: Gerd Hoffmann +(cherry picked from commit 020cc9e2e7053bb62247b0babbbe80cb855592e5) +--- + OvmfPkg/IntelTdx/IntelTdxX64.dsc | 8 ++++++++ + OvmfPkg/Microvm/MicrovmX64.dsc | 8 ++++++++ + OvmfPkg/OvmfXen.dsc | 8 ++++++++ + 3 files changed, 24 insertions(+) + +diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc +index bfcd486976cf..cfd5e8516ea4 100644 +--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc ++++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc +@@ -463,6 +463,14 @@ [PcdsFixedAtBuild] + # Point to the MdeModulePkg/Application/UiApp/UiApp.inf + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + ++ # ++ # PcdFirstTimeWakeUpAPsBySipi determines whether to employ ++ # SIPI instead of the INIT-SIPI-SIPI sequence during APs ++ # initialization. Deactivate this parameter to preserve ++ # the original execution of INIT-SIPI-SIPI. ++ # ++ gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE ++ + ################################################################################ + # + # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc +index 023b7b0fe959..3cb2b6ddc490 100644 +--- a/OvmfPkg/Microvm/MicrovmX64.dsc ++++ b/OvmfPkg/Microvm/MicrovmX64.dsc +@@ -566,6 +566,14 @@ [PcdsFixedAtBuild] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0xFF} + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3f8 + ++ # ++ # PcdFirstTimeWakeUpAPsBySipi determines whether to employ ++ # SIPI instead of the INIT-SIPI-SIPI sequence during APs ++ # initialization. Deactivate this parameter to preserve ++ # the original execution of INIT-SIPI-SIPI. ++ # ++ gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE ++ + ################################################################################ + # + # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc +index 210578c1d74d..dcb99d1f0bce 100644 +--- a/OvmfPkg/OvmfXen.dsc ++++ b/OvmfPkg/OvmfXen.dsc +@@ -458,6 +458,14 @@ [PcdsFixedAtBuild] + # We populate DXE IPL tables with 1G pages preferably on Xen + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE + ++ # ++ # PcdFirstTimeWakeUpAPsBySipi determines whether to employ ++ # SIPI instead of the INIT-SIPI-SIPI sequence during APs ++ # initialization. Deactivate this parameter to preserve ++ # the original execution of INIT-SIPI-SIPI. ++ # ++ gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE ++ + ################################################################################ + # + # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +-- +2.41.0 + diff --git a/0019-OvmfPkg-AmdSev-Disable-PcdFirstTimeWakeUpAPsBySipi.patch b/0019-OvmfPkg-AmdSev-Disable-PcdFirstTimeWakeUpAPsBySipi.patch new file mode 100644 index 0000000..b4c1c62 --- /dev/null +++ b/0019-OvmfPkg-AmdSev-Disable-PcdFirstTimeWakeUpAPsBySipi.patch @@ -0,0 +1,46 @@ +From cb435f3097b28e7470a7653def7d5ab06855f6ee Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Wed, 16 Aug 2023 15:11:46 -0500 +Subject: [PATCH 19/20] OvmfPkg/AmdSev: Disable PcdFirstTimeWakeUpAPsBySipi + +PcdFirstTimeWakeUpAPsBySipi was recently introduced to indicate when the +full INIT-SIPI-SIPI sequence can be skipped for AP bringup. It is true +by default, but needs to be disabled for QEMU/OVMF where early INIT is +not simulated. Commit 1d76560146 ("OvmfPkg: Disable +PcdFirstTimeWakeUpAPsBySipi.") added changes to disable it by default +for OvmfPkg, but a similar change was not made for the AmdSev package. +This breaks booting of SEV and SNP guests. + +Fix this defaulting PcdFirstTimeWakeUpAPsBySipi to false for AmdSev +package, as was previously done for OvmfPkg variants. + +Fixes: eaffa1d7ff ("UefiCpuPkg:Wake up APs after power-up or RESET through SIPI.") +Signed-off-by: Michael Roth +Acked-by: Gerd Hoffmann +(cherry picked from commit 8b66f9df1bb0fd5ebb743944d41cb33178cf2fdd) +--- + OvmfPkg/AmdSev/AmdSevX64.dsc | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc +index 865d150a2871..7f808126675f 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.dsc ++++ b/OvmfPkg/AmdSev/AmdSevX64.dsc +@@ -468,6 +468,14 @@ [PcdsFixedAtBuild] + gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|TRUE + gUefiOvmfPkgTokenSpaceGuid.PcdBootRestrictToFirmware|TRUE + ++ # ++ # INIT is now triggered before BIOS by ucode/hardware. In the OVMF ++ # environment, QEMU lacks a simulation for the INIT process. ++ # To address this, PcdFirstTimeWakeUpAPsBySipi set to FALSE to ++ # broadcast INIT-SIPI-SIPI for the first time. ++ # ++ gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE ++ + ################################################################################ + # + # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +-- +2.41.0 + diff --git a/0020-OvmfPkg-AmdSev-fix-BdsPlatform.c-assertion-failure-d.patch b/0020-OvmfPkg-AmdSev-fix-BdsPlatform.c-assertion-failure-d.patch new file mode 100644 index 0000000..2ece3fb --- /dev/null +++ b/0020-OvmfPkg-AmdSev-fix-BdsPlatform.c-assertion-failure-d.patch @@ -0,0 +1,72 @@ +From 6580637b33ef9b55b6dcfa8517e5933fb87b02d1 Mon Sep 17 00:00:00 2001 +From: "Roth, Michael via groups.io" +Date: Wed, 16 Aug 2023 15:11:45 -0500 +Subject: [PATCH 20/20] OvmfPkg/AmdSev: fix BdsPlatform.c assertion failure + during boot + +Booting an SEV guest with AmdSev OVMF package currently triggers the +following assertion with QEMU: + + InstallQemuFwCfgTables: installed 7 tables + PcRtc: Write 0x20 to CMOS location 0x32 + [Variable]END_OF_DXE is signaled + Initialize variable error flag (FF) + + ASSERT_EFI_ERROR (Status = Not Found) + ASSERT [BdsDxe] /home/VT_BUILD/ovmf/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c(1711): !(((INTN)(RETURN_STATUS)(Status)) < 0) + +This seems to be due to commit 81dc0d8b4c, which switched to using +PlatformBootManagerLib instead of PlatformBootManagerLibGrub. That pulls +in a dependency on gEfiS3SaveStateProtocolGuid provider being available +(which is asserted for in +BdsPlatform.c:PlatformBootManagerBeforeConsole()/SaveS3BootScript()), +but the libraries that provide it aren't currently included in the +build. Add them similarly to what's done for OvmfPkg. + +Fixes: 81dc0d8b4c ("OvmfPkg/AmdSev: stop using PlatformBootManagerLibGrub") +Signed-off-by: Michael Roth +Acked-by: Gerd Hoffmann +Acked-by: Jiewen Yao +(cherry picked from commit f008890ae55929f7f17e7d2f8aff929255007d33) +--- + OvmfPkg/AmdSev/AmdSevX64.dsc | 3 +++ + OvmfPkg/AmdSev/AmdSevX64.fdf | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc +index 7f808126675f..49f6be3a079c 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.dsc ++++ b/OvmfPkg/AmdSev/AmdSevX64.dsc +@@ -200,6 +200,7 @@ [LibraryClasses] + + SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf ++ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf + + !include OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc + +@@ -727,6 +728,8 @@ [Components] + # + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf ++ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf ++ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + + # +diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf +index 463bd3e9ef15..b2ab0c777320 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.fdf ++++ b/OvmfPkg/AmdSev/AmdSevX64.fdf +@@ -270,6 +270,8 @@ [FV.DXEFV] + + INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf ++INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf ++INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf + INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + + INF FatPkg/EnhancedFatDxe/Fat.inf +-- +2.41.0 + diff --git a/edk2.spec b/edk2.spec index 7106967..c8f29de 100644 --- a/edk2.spec +++ b/edk2.spec @@ -109,6 +109,10 @@ Patch0013: 0013-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch Patch0014: 0014-ArmPkg-Add-Pcd-to-disable-EFI_MEMORY_ATTRIBUTE_PROTO.patch Patch0015: 0015-CryptoPkg-CrtLib-add-stat.h.patch Patch0016: 0016-CryptoPkg-CrtLib-add-access-open-read-write-close-sy.patch +Patch0017: 0017-OvmfPkg-IoMmuDxe-don-t-rely-on-TPLs-to-manage-concur.patch +Patch0018: 0018-OvmfPkg-Disable-PcdFirstTimeWakeUpAPsBySipi.patch +Patch0019: 0019-OvmfPkg-AmdSev-Disable-PcdFirstTimeWakeUpAPsBySipi.patch +Patch0020: 0020-OvmfPkg-AmdSev-fix-BdsPlatform.c-assertion-failure-d.patch # python3-devel and libuuid-devel are required for building tools.