From: Tom Lendacky Date: Thu, 15 Dec 2022 05:18:09 +0000 (+0800) Subject: OvmfPkg/IoMmuDxe: Add SEV support for reserved shared memory X-Git-Tag: edk2-stable202302~234 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=47b9521513fd56a9aa0b56dbe15c349325f56bfa OvmfPkg/IoMmuDxe: Add SEV support for reserved shared memory Add support to use the reserved shared memory within the IoMmu library. This improves boot times for all SEV guests, with SEV-SNP benefiting the most as it avoids the page state change call to the hypervisor. Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Min Xu Cc: Gerd Hoffmann Acked-by: Jiewen Yao Signed-off-by: Tom Lendacky --- diff --git a/OvmfPkg/IoMmuDxe/CcIoMmu.c b/OvmfPkg/IoMmuDxe/CcIoMmu.c index 1479af4698..7c2843cd23 100644 --- a/OvmfPkg/IoMmuDxe/CcIoMmu.c +++ b/OvmfPkg/IoMmuDxe/CcIoMmu.c @@ -223,30 +223,32 @@ IoMmuMap ( goto FreeMapInfo; } - if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + if (MapInfo->ReservedMemBitmap == 0) { // - // Clear the memory encryption mask on the plaintext buffer. - // - Status = MemEncryptSevClearPageEncMask ( - 0, - MapInfo->PlainTextAddress, - MapInfo->NumberOfPages - ); - } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { - // - // Set the memory shared bit. // If MapInfo->ReservedMemBitmap is 0, it means the bounce buffer is not allocated // from the pre-allocated shared memory, so it must be converted to shared memory here. // - if (MapInfo->ReservedMemBitmap == 0) { + if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + // + // Clear the memory encryption mask on the plaintext buffer. + // + Status = MemEncryptSevClearPageEncMask ( + 0, + MapInfo->PlainTextAddress, + MapInfo->NumberOfPages + ); + } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + // + // Set the memory shared bit. + // Status = MemEncryptTdxSetPageSharedBit ( 0, MapInfo->PlainTextAddress, MapInfo->NumberOfPages ); + } else { + ASSERT (FALSE); } - } else { - ASSERT (FALSE); } ASSERT_EFI_ERROR (Status); @@ -396,30 +398,30 @@ IoMmuUnmapWorker ( break; } - if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) { - // - // Restore the memory encryption mask on the area we used to hold the - // plaintext. - // - Status = MemEncryptSevSetPageEncMask ( - 0, - MapInfo->PlainTextAddress, - MapInfo->NumberOfPages - ); - } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { - // - // Restore the memory shared bit mask on the area we used to hold the - // plaintext. - // - if (MapInfo->ReservedMemBitmap == 0) { + if (MapInfo->ReservedMemBitmap == 0) { + if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + // + // Restore the memory encryption mask on the area we used to hold the + // plaintext. + // + Status = MemEncryptSevSetPageEncMask ( + 0, + MapInfo->PlainTextAddress, + MapInfo->NumberOfPages + ); + } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + // + // Restore the memory shared bit mask on the area we used to hold the + // plaintext. + // Status = MemEncryptTdxClearPageSharedBit ( 0, MapInfo->PlainTextAddress, MapInfo->NumberOfPages ); + } else { + ASSERT (FALSE); } - } else { - ASSERT (FALSE); } ASSERT_EFI_ERROR (Status); @@ -924,16 +926,14 @@ InstallIoMmuProtocol ( } // - // Currently only Tdx guest support Reserved shared memory for DMA operation. + // For CC guests, use reserved shared memory for DMA operation. // - if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { - mReservedSharedMemSupported = TRUE; - Status = IoMmuInitReservedSharedMem (); - if (EFI_ERROR (Status)) { - mReservedSharedMemSupported = FALSE; - } else { - DEBUG ((DEBUG_INFO, "%a: Feature of reserved memory for DMA is supported.\n", __FUNCTION__)); - } + mReservedSharedMemSupported = TRUE; + Status = IoMmuInitReservedSharedMem (); + if (EFI_ERROR (Status)) { + mReservedSharedMemSupported = FALSE; + } else { + DEBUG ((DEBUG_INFO, "%a: Feature of reserved memory for DMA is supported.\n", __FUNCTION__)); } return EFI_SUCCESS; diff --git a/OvmfPkg/IoMmuDxe/IoMmuBuffer.c b/OvmfPkg/IoMmuDxe/IoMmuBuffer.c index 2675223aa0..83c7c59583 100644 --- a/OvmfPkg/IoMmuDxe/IoMmuBuffer.c +++ b/OvmfPkg/IoMmuDxe/IoMmuBuffer.c @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include "IoMmuInternal.h" @@ -139,6 +141,7 @@ IoMmuInitReservedSharedMem ( UINTN TotalPages; IOMMU_RESERVED_MEM_RANGE *MemRange; EFI_PHYSICAL_ADDRESS PhysicalAddress; + UINT64 SharedAddress; if (!mReservedSharedMemSupported) { return EFI_UNSUPPORTED; @@ -163,12 +166,25 @@ IoMmuInitReservedSharedMem ( MemRange->StartAddressOfMemRange = PhysicalAddress; for (Index2 = 0; Index2 < MemRange->Slots; Index2++) { - Status = MemEncryptTdxSetPageSharedBit ( - 0, - (UINT64)(UINTN)(MemRange->StartAddressOfMemRange + Index2 * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize), - EFI_SIZE_TO_PAGES (MemRange->DataSize) - ); - ASSERT (!EFI_ERROR (Status)); + SharedAddress = (UINT64)(UINTN)(MemRange->StartAddressOfMemRange + Index2 * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize); + + if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + Status = MemEncryptSevClearPageEncMask ( + 0, + SharedAddress, + EFI_SIZE_TO_PAGES (MemRange->DataSize) + ); + ASSERT (!EFI_ERROR (Status)); + } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + Status = MemEncryptTdxSetPageSharedBit ( + 0, + SharedAddress, + EFI_SIZE_TO_PAGES (MemRange->DataSize) + ); + ASSERT (!EFI_ERROR (Status)); + } else { + ASSERT (FALSE); + } } PhysicalAddress += (MemRange->Slots * SIZE_OF_MEM_RANGE (MemRange)); @@ -190,6 +206,7 @@ IoMmuReleaseReservedSharedMem ( EFI_STATUS Status; UINT32 Index1, Index2; IOMMU_RESERVED_MEM_RANGE *MemRange; + UINT64 SharedAddress; if (!mReservedSharedMemSupported) { return EFI_SUCCESS; @@ -198,12 +215,25 @@ IoMmuReleaseReservedSharedMem ( for (Index1 = 0; Index1 < ARRAY_SIZE (mReservedMemRanges); Index1++) { MemRange = &mReservedMemRanges[Index1]; for (Index2 = 0; Index2 < MemRange->Slots; Index2++) { - Status = MemEncryptTdxClearPageSharedBit ( - 0, - (UINT64)(UINTN)(MemRange->StartAddressOfMemRange + Index2 * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize), - EFI_SIZE_TO_PAGES (MemRange->DataSize) - ); - ASSERT (!EFI_ERROR (Status)); + SharedAddress = (UINT64)(UINTN)(MemRange->StartAddressOfMemRange + Index2 * SIZE_OF_MEM_RANGE (MemRange) + MemRange->HeaderSize); + + if (CC_GUEST_IS_SEV (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + Status = MemEncryptSevSetPageEncMask ( + 0, + SharedAddress, + EFI_SIZE_TO_PAGES (MemRange->DataSize) + ); + ASSERT (!EFI_ERROR (Status)); + } else if (CC_GUEST_IS_TDX (PcdGet64 (PcdConfidentialComputingGuestAttr))) { + Status = MemEncryptTdxClearPageSharedBit ( + 0, + SharedAddress, + EFI_SIZE_TO_PAGES (MemRange->DataSize) + ); + ASSERT (!EFI_ERROR (Status)); + } else { + ASSERT (FALSE); + } } }