summaryrefslogtreecommitdiffstats
path: root/OvmfPkg
diff options
context:
space:
mode:
authorBrijesh Singh <brijesh.singh@amd.com>2017-07-06 09:29:08 -0400
committerJordan Justen <jordan.l.justen@intel.com>2017-07-10 21:17:28 -0700
commit09719a01b11b0e3b9fdd273da3afa0dbb68cb662 (patch)
tree5783adb45e4fbca0f2e0a3264229d39101a0e8f1 /OvmfPkg
parent5feae25392ce52b936c34d2ea9f3f006bd37472c (diff)
downloadedk2-09719a01b11b0e3b9fdd273da3afa0dbb68cb662.tar.gz
edk2-09719a01b11b0e3b9fdd273da3afa0dbb68cb662.tar.bz2
edk2-09719a01b11b0e3b9fdd273da3afa0dbb68cb662.zip
OvmfPkg/QemuFwCfgLib: Implement SEV internal function for Dxe phase
When SEV is enabled, the DMA must be performed on unencrypted pages. So when get asked to perfom FWCFG DMA read or write, we allocate a intermediate (bounce buffer) unencrypted buffer and use this buffer for DMA read or write. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c114
-rw-r--r--OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf7
2 files changed, 121 insertions, 0 deletions
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
index ac05f4c347..f8eb03bc3a 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c
@@ -4,6 +4,7 @@
Copyright (C) 2013, Red Hat, Inc.
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
@@ -14,14 +15,36 @@
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
+#include <Uefi.h>
+
+#include <Protocol/IoMmu.h>
+
+#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/QemuFwCfgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemEncryptSevLib.h>
#include "QemuFwCfgLibInternal.h"
STATIC BOOLEAN mQemuFwCfgSupported = FALSE;
STATIC BOOLEAN mQemuFwCfgDmaSupported;
+STATIC EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
+/**
+
+ Returns a boolean indicating whether SEV is enabled
+
+ @retval TRUE SEV is enabled
+ @retval FALSE SEV is disabled
+**/
+BOOLEAN
+InternalQemuFwCfgSevIsEnabled (
+ VOID
+ )
+{
+ return MemEncryptSevIsEnabled ();
+}
/**
Returns a boolean indicating if the firmware configuration interface
@@ -79,6 +102,24 @@ QemuFwCfgInitialize (
mQemuFwCfgDmaSupported = TRUE;
DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
}
+
+ if (mQemuFwCfgDmaSupported && MemEncryptSevIsEnabled ()) {
+ EFI_STATUS Status;
+
+ //
+ // IoMmuDxe driver must have installed the IOMMU protocol. If we are not
+ // able to locate the protocol then something must have gone wrong.
+ //
+ Status = gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmuProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "QemuFwCfgSevDma %a:%a Failed to locate IOMMU protocol.\n",
+ gEfiCallerBaseName, __FUNCTION__));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+ }
+
return RETURN_SUCCESS;
}
@@ -114,3 +155,76 @@ InternalQemuFwCfgDmaIsAvailable (
{
return mQemuFwCfgDmaSupported;
}
+
+/**
+ Allocate a bounce buffer for SEV DMA.
+
+ @param[in] NumPage Number of pages.
+ @param[out] Buffer Allocated DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaAllocateBuffer (
+ OUT VOID **Buffer,
+ IN UINT32 NumPages
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (mIoMmuProtocol != NULL);
+
+ Status = mIoMmuProtocol->AllocateBuffer (
+ mIoMmuProtocol,
+ 0,
+ EfiBootServicesData,
+ NumPages,
+ Buffer,
+ EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to allocate %u pages\n", gEfiCallerBaseName, __FUNCTION__,
+ NumPages));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ DEBUG ((DEBUG_VERBOSE,
+ "%a:%a buffer 0x%Lx Pages %u\n", gEfiCallerBaseName, __FUNCTION__,
+ (UINT64)(UINTN)Buffer, NumPages));
+}
+
+/**
+ Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer
+
+ @param[in] NumPage Number of pages.
+ @param[in] Buffer DMA Buffer pointer
+
+**/
+VOID
+InternalQemuFwCfgSevDmaFreeBuffer (
+ IN VOID *Buffer,
+ IN UINT32 NumPages
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (mIoMmuProtocol != NULL);
+
+ Status = mIoMmuProtocol->FreeBuffer (
+ mIoMmuProtocol,
+ NumPages,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a:%a failed to free buffer 0x%Lx pages %u\n", gEfiCallerBaseName,
+ __FUNCTION__, (UINT64)(UINTN)Buffer, NumPages));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ DEBUG ((DEBUG_VERBOSE,
+ "%a:%a buffer 0x%Lx Pages %u\n", gEfiCallerBaseName,__FUNCTION__,
+ (UINT64)(UINTN)Buffer, NumPages));
+}
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
index d7e368e543..11cbb3c4f3 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
@@ -39,6 +39,7 @@
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
@@ -47,4 +48,10 @@
DebugLib
IoLib
MemoryAllocationLib
+ MemEncryptSevLib
+[Protocols]
+ gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
+
+[Depex]
+ gEdkiiIoMmuProtocolGuid OR gIoMmuAbsentProtocolGuid