OvmfPkg/QemuFwCfgLib: Add SEV support
authorBrijesh Singh <brijesh.singh@amd.com>
Thu, 6 Jul 2017 13:29:19 +0000 (09:29 -0400)
committerJordan Justen <jordan.l.justen@intel.com>
Tue, 11 Jul 2017 04:17:28 +0000 (21:17 -0700)
When SEV is enabled, use a bounce buffer to perform the DMA operation.

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: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c

index 73a1977..dbebd36 100644 (file)
@@ -72,6 +72,8 @@ InternalQemuFwCfgDmaBytes (
   volatile FW_CFG_DMA_ACCESS *Access;\r
   UINT32                     AccessHigh, AccessLow;\r
   UINT32                     Status;\r
+  UINT32                     NumPages;\r
+  VOID                       *DmaBuffer, *BounceBuffer;\r
 \r
   ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||\r
     Control == FW_CFG_DMA_CTL_SKIP);\r
@@ -80,11 +82,44 @@ InternalQemuFwCfgDmaBytes (
     return;\r
   }\r
 \r
-  Access = &LocalAccess;\r
+  //\r
+  // When SEV is enabled then allocate DMA bounce buffer\r
+  //\r
+  if (InternalQemuFwCfgSevIsEnabled ()) {\r
+    UINTN  TotalSize;\r
+\r
+    TotalSize = sizeof (*Access);\r
+    //\r
+    // Skip operation does not need buffer\r
+    //\r
+    if (Control != FW_CFG_DMA_CTL_SKIP) {\r
+      TotalSize += Size;\r
+    }\r
+\r
+    //\r
+    // Allocate SEV DMA buffer\r
+    //\r
+    NumPages = (UINT32)EFI_SIZE_TO_PAGES (TotalSize);\r
+    InternalQemuFwCfgSevDmaAllocateBuffer (&BounceBuffer, NumPages);\r
+\r
+    Access = BounceBuffer;\r
+    DmaBuffer = (UINT8*)BounceBuffer + sizeof (*Access);\r
+\r
+    //\r
+    //  Decrypt data from encrypted guest buffer into DMA buffer\r
+    //\r
+    if (Control == FW_CFG_DMA_CTL_WRITE) {\r
+      CopyMem (DmaBuffer, Buffer, Size);\r
+    }\r
+  } else {\r
+    Access = &LocalAccess;\r
+    DmaBuffer = Buffer;\r
+    BounceBuffer = NULL;\r
+  }\r
 \r
   Access->Control = SwapBytes32 (Control);\r
   Access->Length  = SwapBytes32 (Size);\r
-  Access->Address = SwapBytes64 ((UINTN)Buffer);\r
+  Access->Address = SwapBytes64 ((UINTN)DmaBuffer);\r
 \r
   //\r
   // Delimit the transfer from (a) modifications to Access, (b) in case of a\r
@@ -117,6 +152,21 @@ InternalQemuFwCfgDmaBytes (
   // After a read, the caller will want to use Buffer.\r
   //\r
   MemoryFence ();\r
+\r
+  //\r
+  // If Bounce buffer was allocated then copy the data into guest buffer and\r
+  // free the bounce buffer\r
+  //\r
+  if (BounceBuffer != NULL) {\r
+    //\r
+    //  Encrypt the data from DMA buffer into guest buffer\r
+    //\r
+    if (Control == FW_CFG_DMA_CTL_READ) {\r
+      CopyMem (Buffer, DmaBuffer, Size);\r
+    }\r
+\r
+    InternalQemuFwCfgSevDmaFreeBuffer (BounceBuffer, NumPages);\r
+  }\r
 }\r
 \r
 \r