diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf index ba2d3679a4..b5c79762c2 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf @@ -40,6 +40,7 @@ FwBlockService.c FwBlockServiceSmm.c QemuFlash.c + QemuFlashSmm.c [Packages] MdePkg/MdePkg.dec @@ -53,6 +54,7 @@ DevicePathLib DxeServicesTableLib MemoryAllocationLib + MemEncryptSevLib PcdLib SmmServicesTableLib UefiBootServicesTableLib diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c index 5677b5ee11..462d9c0322 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c @@ -244,6 +244,15 @@ QemuFlashInitialize ( ASSERT(PcdGet32 (PcdOvmfFirmwareFdSize) % mFdBlockSize == 0); mFdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / mFdBlockSize; + // + // execute module specific hooks before probing the flash + // + QemuFlashBeforeProbe ( + (EFI_PHYSICAL_ADDRESS)(UINTN) mFlashBase, + mFdBlockSize, + mFdBlockCount + ); + if (!QemuFlashDetected ()) { ASSERT (!FeaturePcdGet (PcdSmmSmramRequire)); return EFI_WRITE_PROTECTED; diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h index 8d83dca7a5..d34a8a19a0 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h @@ -88,5 +88,12 @@ QemuFlashConvertPointers ( VOID ); +VOID +QemuFlashBeforeProbe ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN FdBlockSize, + IN UINTN FdBlockCount + ); + #endif diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c index 08ece2beae..332ceafd3f 100644 --- a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashDxe.c @@ -26,3 +26,15 @@ QemuFlashConvertPointers ( { EfiConvertPointer (0x0, (VOID **) &mFlashBase); } + +VOID +QemuFlashBeforeProbe ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN FdBlockSize, + IN UINTN FdBlockCount + ) +{ + // + // Do nothing + // +} diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c new file mode 100644 index 0000000000..8999ad8d0d --- /dev/null +++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlashSmm.c @@ -0,0 +1,54 @@ +/** @file + Define the module hooks used while probing the QEMU flash device. + + Copyright (C) 2018, Advanced Micro Devices. All rights reserved. + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include + +#include "QemuFlash.h" + +VOID +QemuFlashBeforeProbe ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN FdBlockSize, + IN UINTN FdBlockCount + ) +{ + EFI_STATUS Status; + + ASSERT (FeaturePcdGet (PcdSmmSmramRequire)); + + if (!MemEncryptSevIsEnabled ()) { + return; + } + + // + // When SEV is enabled, AmdSevDxe runs early in DXE phase and clears the + // C-bit from the NonExistent entry -- which is later split and accommodate + // the flash MMIO 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. + // + + Status = MemEncryptSevClearPageEncMask ( + 0, + BaseAddress, + EFI_SIZE_TO_PAGES (FdBlockSize * FdBlockCount), + FALSE + ); + ASSERT_EFI_ERROR (Status); +}