Commit:24e4ad7 (OvmfPkg: Add AmdSevDxe driver) added a driver which runs early in PEI phase and clears the C-bit from all MMIO regions (including Qemu Flash). When SMM is enabled, we build two sets of page tables; first page table is used when executing code in non SMM mode (SMM-less-pgtable) and second page table is used when we are executing code in SMM mode (SMM-pgtable).
During boot time, AmdSevDxe driver clears the C-bit from the SMM-less-pgtable. But when SMM is enabled, Qemu Flash services are used from SMM mode. In this patch we explicitly clear the C-bit from Qemu flash MMIO range before we probe the flash. When OVMF is built with SMM_REQUIRE then call to initialize the flash services happen after the SMM-pgtable is created and processor is serving the first SMI. At this time we will have access to the SMM-pgtable. Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Cc: Ard Biesheuvel <ard.biesheu...@linaro.org> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Brijesh Singh <brijesh.si...@amd.com> --- OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf | 1 + OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h | 5 +++ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c | 5 +++ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c | 10 ++++++ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c | 35 ++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf index ba2d3679a46d..d365e27cbe59 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf @@ -53,6 +53,7 @@ [LibraryClasses] DevicePathLib DxeServicesTableLib MemoryAllocationLib + MemEncryptSevLib PcdLib SmmServicesTableLib UefiBootServicesTableLib diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h index 1f9287b08769..704ed477ba14 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h @@ -189,4 +189,9 @@ VOID InstallVirtualAddressChangeHandler ( VOID ); + +VOID +FvbBeforeFlashProbe ( + VOID + ); #endif diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c index 558b395dff4a..b7b9bf1fb8d9 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c @@ -967,6 +967,11 @@ FvbInitialize ( UINTN NumOfBlocks; RETURN_STATUS PcdStatus; + // + // execute platform specific hooks before probing the flash + // + FvbBeforeFlashProbe (); + if (EFI_ERROR (QemuFlashInitialize ())) { // // Return an error so image will be unloaded diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c index 63b308658e36..7d274c08ad12 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceDxe.c @@ -155,3 +155,13 @@ InstallVirtualAddressChangeHandler ( ); ASSERT_EFI_ERROR (Status); } + +VOID +FvbBeforeFlashProbe ( + VOID + ) +{ + // + // Do nothing + // +} diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c index e0617f2503a2..d97b13f47bf7 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockServiceSmm.c @@ -17,6 +17,7 @@ #include <Library/DebugLib.h> #include <Library/PcdLib.h> #include <Library/SmmServicesTableLib.h> +#include <Library/MemEncryptSevLib.h> #include <Protocol/DevicePath.h> #include <Protocol/SmmFirmwareVolumeBlock.h> @@ -67,3 +68,37 @@ InstallVirtualAddressChangeHandler ( // Nothing. // } + +VOID +FvbBeforeFlashProbe ( + VOID + ) +{ + + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); + + // + // When SEV is enabled, AmdSevDxe runs early in PEI phase and clears the C-bit + // from the MMIO space (including flash ranges) but the driver runs in non SMM + // context hence it cleared the flash ranges from non SMM page table. + // When SMM is enabled, the flash services are accessed from the SMM mode + // hence we explicitly clear the C-bit on flash ranges from SMM page table. + // + if (MemEncryptSevIsEnabled ()) { + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINTN FdBlockSize, FdBlockCount; + + BaseAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdOvmfFdBaseAddress); + FdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize); + FdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / FdBlockSize; + + Status = MemEncryptSevClearPageEncMask ( + 0, + BaseAddress, + EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount), + FALSE + ); + ASSERT_EFI_ERROR (Status); + } +} -- 2.14.3 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel