When iommu_platform is set, use IOMMU protocols buffer allocation and free routines to allocate and free vring buffer (guest-host communication buffer).
Cc: Jordan Justen <[email protected]> Cc: Laszlo Ersek <[email protected]> Cc: Jason Wang <[email protected]> Cc: Michael S. Tsirkin <[email protected]> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Brijesh Singh <[email protected]> --- OvmfPkg/Library/VirtioLib/VirtioLib.inf | 1 + OvmfPkg/VirtioBlkDxe/VirtioBlk.inf | 1 + OvmfPkg/VirtioGpuDxe/VirtioGpu.inf | 1 + OvmfPkg/VirtioNetDxe/VirtioNet.inf | 1 + OvmfPkg/VirtioRngDxe/VirtioRng.inf | 1 + OvmfPkg/VirtioScsiDxe/VirtioScsi.inf | 1 + OvmfPkg/Include/IndustryStandard/Virtio095.h | 1 + OvmfPkg/Include/Library/VirtioLib.h | 20 ++++ OvmfPkg/Library/VirtioLib/VirtioLib.c | 96 +++++++++++++++++++- 9 files changed, 121 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.inf b/OvmfPkg/Library/VirtioLib/VirtioLib.inf index fb5897a88ecf..6629d0d52b04 100644 --- a/OvmfPkg/Library/VirtioLib/VirtioLib.inf +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.inf @@ -26,6 +26,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf index d5975b74eb05..53d5a164a0b8 100644 --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.inf @@ -26,6 +26,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf index 04bc2964c223..a6d4cbbd191a 100644 --- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf +++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf @@ -31,6 +31,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] diff --git a/OvmfPkg/VirtioNetDxe/VirtioNet.inf b/OvmfPkg/VirtioNetDxe/VirtioNet.inf index a855ad4ac154..2b8996ed366e 100644 --- a/OvmfPkg/VirtioNetDxe/VirtioNet.inf +++ b/OvmfPkg/VirtioNetDxe/VirtioNet.inf @@ -42,6 +42,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.inf b/OvmfPkg/VirtioRngDxe/VirtioRng.inf index 471beb37bc7f..898bfb7158c2 100644 --- a/OvmfPkg/VirtioRngDxe/VirtioRng.inf +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.inf @@ -26,6 +26,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf b/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf index 75581123930b..082f9a12bb09 100644 --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.inf @@ -27,6 +27,7 @@ [Sources] [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] diff --git a/OvmfPkg/Include/IndustryStandard/Virtio095.h b/OvmfPkg/Include/IndustryStandard/Virtio095.h index 6bf77cb32075..c81b29c6d9d0 100644 --- a/OvmfPkg/Include/IndustryStandard/Virtio095.h +++ b/OvmfPkg/Include/IndustryStandard/Virtio095.h @@ -154,6 +154,7 @@ typedef struct { VRING_AVAIL Avail; VRING_USED Used; UINT16 QueueSize; + VOID *Iommu; } VRING; // diff --git a/OvmfPkg/Include/Library/VirtioLib.h b/OvmfPkg/Include/Library/VirtioLib.h index 5badfb32917f..92a3d5e10f7b 100644 --- a/OvmfPkg/Include/Library/VirtioLib.h +++ b/OvmfPkg/Include/Library/VirtioLib.h @@ -17,10 +17,30 @@ #ifndef _VIRTIO_LIB_H_ #define _VIRTIO_LIB_H_ +#include <Protocol/IoMmu.h> #include <Protocol/VirtioDevice.h> #include <IndustryStandard/Virtio.h> +/** + + Configure a virtio ring to use IOMMU protocol + + This function tells vring to use the given IOMMU protocol interface + for allocating and freeing the vring buffer (this guest-host communication + area) + + @param[in] The virtio ring to set up. + + @param[in] IOMMU protocol to use. + +**/ +VOID +EFIAPI +VirtioRingUseIommu ( + IN VRING *Ring, + IN EDKII_IOMMU_PROTOCOL *Iommu + ); /** diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c b/OvmfPkg/Library/VirtioLib/VirtioLib.c index 845f206369a3..d8fdb6310d52 100644 --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c @@ -26,6 +26,69 @@ /** + Configure a virtio ring to use IOMMU protocol + + This function tells vring to use the given IOMMU protocol interface + for allocating and freeing the vring buffer (this guest-host communication + area) + + @param[in] The virtio ring to set up. + + @param[in] IOMMU protocol to use. + +**/ +VOID +EFIAPI +VirtioRingUseIommu ( + IN VRING *Ring, + IN EDKII_IOMMU_PROTOCOL *Iommu + ) +{ + Ring->Iommu = Iommu; +} + +/** + + Allocate vring (the guest-host communication area) + + This function checks if host has requested the Iommu support then it uses + the IOMMU protocol allocator for allocating vring otherwise uses AllocatePages + +**/ +STATIC +VOID * +VirtioRingAllocatePages ( + IN VRING *Ring + ) +{ + UINT32 NumPages; + EDKII_IOMMU_PROTOCOL *Iommu; + + NumPages = Ring->NumPages; + Iommu = (EDKII_IOMMU_PROTOCOL *)Ring->Iommu; + + // + // If IOMMU protocol is set then use IOMMU allocator otherwise + // fallback to standard allocator + // + if (Iommu) { + EFI_STATUS Status; + VOID *Buffer; + + Status = Iommu->AllocateBuffer (Iommu, 0, EfiBootServicesData, + NumPages, &Buffer, EDKII_IOMMU_ATTRIBUTE_MEMORY_CACHED); + if (EFI_ERROR (Status)) { + return NULL; + } + + return Buffer; + } + + return AllocatePages (NumPages); +} + +/** + Configure a virtio ring. This function sets up internal storage (the guest-host communication area) @@ -76,7 +139,7 @@ VirtioRingInit ( EFI_PAGE_SIZE); Ring->NumPages = EFI_SIZE_TO_PAGES (RingSize); - Ring->Base = AllocatePages (Ring->NumPages); + Ring->Base = VirtioRingAllocatePages (Ring); if (Ring->Base == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -118,6 +181,35 @@ VirtioRingInit ( return EFI_SUCCESS; } +/** + + Free vring (the guest-host communication area) + + This function checks if host has requested the Iommu support then it uses + the IOMMU protocol free callback otherwise uses FreePages + +**/ +STATIC +VOID +VirtioRingFreePages ( + IN VRING *Ring + ) +{ + EDKII_IOMMU_PROTOCOL *Iommu; + + Iommu = (EDKII_IOMMU_PROTOCOL *)Ring->Iommu; + + // + // If IOMMU protocol is set then use IOMMU FreeBuffer otherwise + // fallback to FreePages + // + if (Iommu) { + Iommu->FreeBuffer (Iommu, Ring->NumPages, Ring->Base); + } else { + FreePages (Ring->Base, Ring->NumPages); + } +} + /** @@ -136,7 +228,7 @@ VirtioRingUninit ( IN OUT VRING *Ring ) { - FreePages (Ring->Base, Ring->NumPages); + VirtioRingFreePages (Ring); SetMem (Ring, sizeof *Ring, 0x00); } -- 2.7.4 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

