From 5ffb4fbb834aabc1b79886af629d688bacf88386 Mon Sep 17 00:00:00 2001 From: Oliver Steffen Date: Mon, 26 Aug 2024 11:07:38 -0400 Subject: [PATCH] OvmfPkg/AmdSevDxe: Shim Reboot workaround Add a callback at the end of the Dxe phase that sets the "FB_NO_REBOOT" variable under the Shim GUID. This is a workaround for a boot loop in case a confidential guest that uses shim is booted with a vtpm device present. Signed-off-by: Oliver Steffen --- OvmfPkg/AmdSevDxe/AmdSevDxe.c | 45 +++++++++++++++++++++++++++++++++ OvmfPkg/AmdSevDxe/AmdSevDxe.inf | 2 ++ 2 files changed, 47 insertions(+) diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.c b/OvmfPkg/AmdSevDxe/AmdSevDxe.c index db3675ae86a9b..c20dd49560168 100644 --- a/OvmfPkg/AmdSevDxe/AmdSevDxe.c +++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,10 @@ // Present, initialized, tested bits defined in MdeModulePkg/Core/Dxe/DxeMain.h #define EFI_MEMORY_INTERNAL_MASK 0x0700000000000000ULL +static EFI_GUID ShimLockGuid = { + 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } +}; + STATIC EFI_STATUS AllocateConfidentialComputingBlob ( @@ -191,6 +196,32 @@ STATIC EDKII_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = { AmdSevMemoryAccept }; +VOID +EFIAPI +PopulateVarstore ( + EFI_EVENT Event, + VOID *Context + ) +{ + EFI_SYSTEM_TABLE *SystemTable = (EFI_SYSTEM_TABLE *)Context; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "Populating Varstore\n")); + UINT32 data = 1; + + Status = SystemTable->RuntimeServices->SetVariable ( + L"FB_NO_REBOOT", + &ShimLockGuid, + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (data), + &data + ); + ASSERT_EFI_ERROR (Status); + + Status = SystemTable->BootServices->CloseEvent (Event); + ASSERT_EFI_ERROR (Status); +} + EFI_STATUS EFIAPI AmdSevDxeEntryPoint ( @@ -203,6 +234,7 @@ AmdSevDxeEntryPoint ( UINTN NumEntries; UINTN Index; CONFIDENTIAL_COMPUTING_SNP_BLOB_LOCATION *SnpBootDxeTable; + EFI_EVENT PopulateVarstoreEvent; // // Do nothing when SEV is not enabled @@ -211,6 +243,17 @@ AmdSevDxeEntryPoint ( return EFI_UNSUPPORTED; } + // Workaround for shim fallback reboot + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + PopulateVarstore, + SystemTable, + &gEfiEndOfDxeEventGroupGuid, + &PopulateVarstoreEvent + ); + ASSERT_EFI_ERROR (Status); + // // Iterate through the GCD map and clear the C-bit from MMIO and NonExistent // memory space. The NonExistent memory space will be used for mapping the @@ -320,6 +363,7 @@ AmdSevDxeEntryPoint ( CpuDeadLoop (); } + if (MemEncryptSevSnpIsEnabled ()) { // // Memory acceptance began being required in SEV-SNP, so install the @@ -361,5 +405,6 @@ AmdSevDxeEntryPoint ( ); } + return EFI_SUCCESS; } diff --git a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf index e7c7d526c95f9..09cbd2b0ca233 100644 --- a/OvmfPkg/AmdSevDxe/AmdSevDxe.inf +++ b/OvmfPkg/AmdSevDxe/AmdSevDxe.inf @@ -54,6 +54,8 @@ [Guids] gConfidentialComputingSevSnpBlobGuid gEfiEventBeforeExitBootServicesGuid + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event + [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId