X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FLibrary%2FQemuFwCfgLib%2FQemuFwCfgLib.c;h=dbebd36b18530dbebac6f7fc1e7a1ea4fd4c2966;hp=3dd55ba5042ea4f1ef28d1895b0a4497e0504c89;hb=66c548be509d;hpb=ed1a2d42d5d54b6096b6e5121b0e5b7410b24108 diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c index 3dd55ba504..dbebd36b18 100644 --- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c @@ -68,9 +68,12 @@ InternalQemuFwCfgDmaBytes ( IN UINT32 Control ) { - volatile FW_CFG_DMA_ACCESS Access; + volatile FW_CFG_DMA_ACCESS LocalAccess; + volatile FW_CFG_DMA_ACCESS *Access; UINT32 AccessHigh, AccessLow; UINT32 Status; + UINT32 NumPages; + VOID *DmaBuffer, *BounceBuffer; ASSERT (Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ || Control == FW_CFG_DMA_CTL_SKIP); @@ -79,9 +82,44 @@ InternalQemuFwCfgDmaBytes ( return; } - Access.Control = SwapBytes32 (Control); - Access.Length = SwapBytes32 (Size); - Access.Address = SwapBytes64 ((UINTN)Buffer); + // + // When SEV is enabled then allocate DMA bounce buffer + // + if (InternalQemuFwCfgSevIsEnabled ()) { + UINTN TotalSize; + + TotalSize = sizeof (*Access); + // + // Skip operation does not need buffer + // + if (Control != FW_CFG_DMA_CTL_SKIP) { + TotalSize += Size; + } + + // + // Allocate SEV DMA buffer + // + NumPages = (UINT32)EFI_SIZE_TO_PAGES (TotalSize); + InternalQemuFwCfgSevDmaAllocateBuffer (&BounceBuffer, NumPages); + + Access = BounceBuffer; + DmaBuffer = (UINT8*)BounceBuffer + sizeof (*Access); + + // + // Decrypt data from encrypted guest buffer into DMA buffer + // + if (Control == FW_CFG_DMA_CTL_WRITE) { + CopyMem (DmaBuffer, Buffer, Size); + } + } else { + Access = &LocalAccess; + DmaBuffer = Buffer; + BounceBuffer = NULL; + } + + Access->Control = SwapBytes32 (Control); + Access->Length = SwapBytes32 (Size); + Access->Address = SwapBytes64 ((UINTN)DmaBuffer); // // Delimit the transfer from (a) modifications to Access, (b) in case of a @@ -92,8 +130,8 @@ InternalQemuFwCfgDmaBytes ( // // Start the transfer. // - AccessHigh = (UINT32)RShiftU64 ((UINTN)&Access, 32); - AccessLow = (UINT32)(UINTN)&Access; + AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32); + AccessLow = (UINT32)(UINTN)Access; IoWrite32 (FW_CFG_IO_DMA_ADDRESS, SwapBytes32 (AccessHigh)); IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow)); @@ -106,7 +144,7 @@ InternalQemuFwCfgDmaBytes ( // Wait for the transfer to complete. // do { - Status = SwapBytes32 (Access.Control); + Status = SwapBytes32 (Access->Control); ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0); } while (Status != 0); @@ -114,6 +152,21 @@ InternalQemuFwCfgDmaBytes ( // After a read, the caller will want to use Buffer. // MemoryFence (); + + // + // If Bounce buffer was allocated then copy the data into guest buffer and + // free the bounce buffer + // + if (BounceBuffer != NULL) { + // + // Encrypt the data from DMA buffer into guest buffer + // + if (Control == FW_CFG_DMA_CTL_READ) { + CopyMem (Buffer, DmaBuffer, Size); + } + + InternalQemuFwCfgSevDmaFreeBuffer (BounceBuffer, NumPages); + } } @@ -368,31 +421,3 @@ QemuFwCfgFindFile ( return RETURN_NOT_FOUND; } - - -/** - Determine if S3 support is explicitly enabled. - - @retval TRUE if S3 support is explicitly enabled. - FALSE otherwise. This includes unavailability of the firmware - configuration interface. -**/ -BOOLEAN -EFIAPI -QemuFwCfgS3Enabled ( - VOID - ) -{ - RETURN_STATUS Status; - FIRMWARE_CONFIG_ITEM FwCfgItem; - UINTN FwCfgSize; - UINT8 SystemStates[6]; - - Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize); - if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) { - return FALSE; - } - QemuFwCfgSelectItem (FwCfgItem); - QemuFwCfgReadBytes (sizeof SystemStates, SystemStates); - return (BOOLEAN) (SystemStates[3] & BIT7); -}